go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/l3plugin/vppcalls/vpp2210/vppcalls_handlers.go (about)

     1  //  Copyright (c) 2022 Cisco and/or its affiliates.
     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 vpp2210
    16  
    17  import (
    18  	"fmt"
    19  	"net"
    20  
    21  	govppapi "go.fd.io/govpp/api"
    22  	"go.ligato.io/cn-infra/v2/logging"
    23  	"go.ligato.io/cn-infra/v2/logging/logrus"
    24  
    25  	corevppcalls "go.ligato.io/vpp-agent/v3/plugins/govppmux/vppcalls"
    26  	vpe_vpp2210 "go.ligato.io/vpp-agent/v3/plugins/govppmux/vppcalls/vpp2210"
    27  	"go.ligato.io/vpp-agent/v3/plugins/netalloc"
    28  	"go.ligato.io/vpp-agent/v3/plugins/vpp"
    29  	vpp2210 "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210"
    30  	vpp_dhcp "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210/dhcp"
    31  	vpp_ip "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210/ip"
    32  	vpp_ip_neighbor "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210/ip_neighbor"
    33  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210/ip_types"
    34  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210/l3xc"
    35  	vpp_vpe "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210/vpe"
    36  	"go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/ifaceidx"
    37  	"go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/vppcalls"
    38  	"go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/vrfidx"
    39  )
    40  
    41  func init() {
    42  	var msgs []govppapi.Message
    43  	msgs = append(msgs, vpp_ip.AllMessages()...)
    44  	msgs = append(msgs, vpp_ip_neighbor.AllMessages()...)
    45  	msgs = append(msgs, vpp_vpe.AllMessages()...)
    46  	msgs = append(msgs, vpp_dhcp.AllMessages()...)
    47  
    48  	vppcalls.AddHandlerVersion(vpp2210.Version, msgs, NewL3VppHandler)
    49  }
    50  
    51  type L3VppHandler struct {
    52  	*ArpVppHandler
    53  	*ProxyArpVppHandler
    54  	*RouteHandler
    55  	*IPNeighHandler
    56  	*VrfTableHandler
    57  	*DHCPProxyHandler
    58  	*L3XCHandler
    59  	*TeibHandler
    60  	*VrrpVppHandler
    61  }
    62  
    63  func NewL3VppHandler(
    64  	c vpp.Client,
    65  	ifIdx ifaceidx.IfaceMetadataIndex,
    66  	vrfIdx vrfidx.VRFMetadataIndex,
    67  	addrAlloc netalloc.AddressAllocator,
    68  	log logging.Logger,
    69  ) vppcalls.L3VppAPI {
    70  	ch, err := c.NewAPIChannel()
    71  	if err != nil {
    72  		logging.Warnf("creating channel failed: %v", err)
    73  		return nil
    74  	}
    75  	return &L3VppHandler{
    76  		ArpVppHandler:      NewArpVppHandler(ch, ifIdx, log),
    77  		ProxyArpVppHandler: NewProxyArpVppHandler(ch, ifIdx, log),
    78  		RouteHandler:       NewRouteVppHandler(ch, ifIdx, vrfIdx, addrAlloc, log),
    79  		IPNeighHandler:     NewIPNeighVppHandler(c, ch, log),
    80  		VrfTableHandler:    NewVrfTableVppHandler(ch, log),
    81  		DHCPProxyHandler:   NewDHCPProxyHandler(ch, log),
    82  		L3XCHandler:        NewL3XCHandler(c, ifIdx, log),
    83  		TeibHandler:        NewTeibVppHandler(ch, ifIdx, log),
    84  		VrrpVppHandler:     NewVrrpVppHandler(ch, ifIdx, log),
    85  	}
    86  }
    87  
    88  // ArpVppHandler is accessor for ARP-related vppcalls methods
    89  type ArpVppHandler struct {
    90  	callsChannel govppapi.Channel
    91  	ifIndexes    ifaceidx.IfaceMetadataIndex
    92  	log          logging.Logger
    93  }
    94  
    95  // DHCPProxyHandler is accessor for DHCP proxy-related vppcalls methods
    96  type DHCPProxyHandler struct {
    97  	callsChannel govppapi.Channel
    98  	log          logging.Logger
    99  }
   100  
   101  // ProxyArpVppHandler is accessor for proxy ARP-related vppcalls methods
   102  type ProxyArpVppHandler struct {
   103  	callsChannel govppapi.Channel
   104  	ifIndexes    ifaceidx.IfaceMetadataIndex
   105  	log          logging.Logger
   106  }
   107  
   108  // RouteHandler is accessor for route-related vppcalls methods
   109  type RouteHandler struct {
   110  	callsChannel govppapi.Channel
   111  	ifIndexes    ifaceidx.IfaceMetadataIndex
   112  	vrfIndexes   vrfidx.VRFMetadataIndex
   113  	addrAlloc    netalloc.AddressAllocator
   114  	log          logging.Logger
   115  }
   116  
   117  // IPNeighHandler is accessor for ip-neighbor-related vppcalls methods
   118  type IPNeighHandler struct {
   119  	callsChannel govppapi.Channel
   120  	log          logging.Logger
   121  	corevppcalls.VppCoreAPI
   122  }
   123  
   124  // VrfTableHandler is accessor for vrf-related vppcalls methods
   125  type VrfTableHandler struct {
   126  	callsChannel govppapi.Channel
   127  	log          logging.Logger
   128  }
   129  
   130  // TeibHandler is accessor for TEIB-related vppcalls methods
   131  type TeibHandler struct {
   132  	callsChannel govppapi.Channel
   133  	ifIndexes    ifaceidx.IfaceMetadataIndex
   134  	log          logging.Logger
   135  }
   136  
   137  // VrrpVppHandler is accessor for vrrp-related vppcalls methods
   138  type VrrpVppHandler struct {
   139  	callsChannel govppapi.Channel
   140  	ifIndexes    ifaceidx.IfaceMetadataIndex
   141  	log          logging.Logger
   142  }
   143  
   144  // NewArpVppHandler creates new instance of IPsec vppcalls handler
   145  func NewArpVppHandler(callsChan govppapi.Channel, ifIndexes ifaceidx.IfaceMetadataIndex, log logging.Logger) *ArpVppHandler {
   146  	if log == nil {
   147  		log = logrus.NewLogger("arp-handler")
   148  	}
   149  	return &ArpVppHandler{
   150  		callsChannel: callsChan,
   151  		ifIndexes:    ifIndexes,
   152  		log:          log,
   153  	}
   154  }
   155  
   156  // NewProxyArpVppHandler creates new instance of proxy ARP vppcalls handler
   157  func NewProxyArpVppHandler(callsChan govppapi.Channel, ifIndexes ifaceidx.IfaceMetadataIndex, log logging.Logger) *ProxyArpVppHandler {
   158  	if log == nil {
   159  		log = logrus.NewLogger("proxy-arp-handler")
   160  	}
   161  	return &ProxyArpVppHandler{
   162  		callsChannel: callsChan,
   163  		ifIndexes:    ifIndexes,
   164  		log:          log,
   165  	}
   166  }
   167  
   168  // NewRouteVppHandler creates new instance of route vppcalls handler
   169  func NewRouteVppHandler(callsChan govppapi.Channel, ifIndexes ifaceidx.IfaceMetadataIndex,
   170  	vrfIdx vrfidx.VRFMetadataIndex, addrAlloc netalloc.AddressAllocator, log logging.Logger) *RouteHandler {
   171  	if log == nil {
   172  		log = logrus.NewLogger("route-handler")
   173  	}
   174  	return &RouteHandler{
   175  		callsChannel: callsChan,
   176  		ifIndexes:    ifIndexes,
   177  		vrfIndexes:   vrfIdx,
   178  		addrAlloc:    addrAlloc,
   179  		log:          log,
   180  	}
   181  }
   182  
   183  // NewIPNeighVppHandler creates new instance of ip neighbor vppcalls handler
   184  func NewIPNeighVppHandler(c vpp.Client, callsChan govppapi.Channel, log logging.Logger) *IPNeighHandler {
   185  	if log == nil {
   186  		log = logrus.NewLogger("ip-neigh")
   187  	}
   188  	return &IPNeighHandler{
   189  		callsChannel: callsChan,
   190  		log:          log,
   191  		VppCoreAPI:   vpe_vpp2210.NewVpeHandler(c),
   192  	}
   193  }
   194  
   195  // NewVrfTableVppHandler creates new instance of vrf-table vppcalls handler
   196  func NewVrfTableVppHandler(callsChan govppapi.Channel, log logging.Logger) *VrfTableHandler {
   197  	if log == nil {
   198  		log = logrus.NewLogger("vrf-table-handler")
   199  	}
   200  	return &VrfTableHandler{
   201  		callsChannel: callsChan,
   202  		log:          log,
   203  	}
   204  }
   205  
   206  // NewDHCPProxyHandler creates new instance of vrf-table vppcalls handler
   207  func NewDHCPProxyHandler(callsChan govppapi.Channel, log logging.Logger) *DHCPProxyHandler {
   208  	if log == nil {
   209  		log = logrus.NewLogger("dhcp-proxy-handler")
   210  	}
   211  	return &DHCPProxyHandler{
   212  		callsChannel: callsChan,
   213  		log:          log,
   214  	}
   215  }
   216  
   217  // NewTeibVppHandler creates new instance of TEIB vppcalls handler
   218  func NewTeibVppHandler(callsChan govppapi.Channel, ifIndexes ifaceidx.IfaceMetadataIndex, log logging.Logger) *TeibHandler {
   219  	if log == nil {
   220  		log = logrus.NewLogger("teib-handler")
   221  	}
   222  	return &TeibHandler{
   223  		callsChannel: callsChan,
   224  		ifIndexes:    ifIndexes,
   225  		log:          log,
   226  	}
   227  }
   228  
   229  type L3XCHandler struct {
   230  	l3xc      l3xc.RPCService
   231  	ifIndexes ifaceidx.IfaceMetadataIndex
   232  	log       logging.Logger
   233  }
   234  
   235  // NewL3XCHandler creates new instance of L3XC vppcalls handler
   236  func NewL3XCHandler(c vpp.Client, ifIndexes ifaceidx.IfaceMetadataIndex, log logging.Logger) *L3XCHandler {
   237  	if log == nil {
   238  		log = logrus.NewLogger("l3xc-handler")
   239  	}
   240  	h := &L3XCHandler{
   241  		ifIndexes: ifIndexes,
   242  		log:       log,
   243  	}
   244  	if c.IsPluginLoaded(l3xc.APIFile) {
   245  		h.l3xc = l3xc.NewServiceClient(c)
   246  	}
   247  	return h
   248  }
   249  
   250  // NewVrrpVppHandler creates new instance of VRRP handler
   251  func NewVrrpVppHandler(callsChan govppapi.Channel, ifIndexes ifaceidx.IfaceMetadataIndex, log logging.Logger) *VrrpVppHandler {
   252  	if log == nil {
   253  		log = logrus.NewLogger("vrrp-handler")
   254  	}
   255  	return &VrrpVppHandler{
   256  		callsChannel: callsChan,
   257  		ifIndexes:    ifIndexes,
   258  		log:          log,
   259  	}
   260  }
   261  
   262  func ipToAddress(ipstr string) (addr ip_types.Address, err error) {
   263  	netIP := net.ParseIP(ipstr)
   264  	if netIP == nil {
   265  		return ip_types.Address{}, fmt.Errorf("invalid IP: %q", ipstr)
   266  	}
   267  	if ip4 := netIP.To4(); ip4 == nil {
   268  		addr.Af = ip_types.ADDRESS_IP6
   269  		var ip6addr ip_types.IP6Address
   270  		copy(ip6addr[:], netIP.To16())
   271  		addr.Un.SetIP6(ip6addr)
   272  	} else {
   273  		addr.Af = ip_types.ADDRESS_IP4
   274  		var ip4addr ip_types.IP4Address
   275  		copy(ip4addr[:], ip4)
   276  		addr.Un.SetIP4(ip4addr)
   277  	}
   278  	return
   279  }
   280  
   281  func networkToPrefix(dstNetwork *net.IPNet) ip_types.Prefix {
   282  	var addr ip_types.Address
   283  	if dstNetwork.IP.To4() == nil {
   284  		addr.Af = ip_types.ADDRESS_IP6
   285  		var ip6addr ip_types.IP6Address
   286  		copy(ip6addr[:], dstNetwork.IP.To16())
   287  		addr.Un.SetIP6(ip6addr)
   288  	} else {
   289  		addr.Af = ip_types.ADDRESS_IP4
   290  		var ip4addr ip_types.IP4Address
   291  		copy(ip4addr[:], dstNetwork.IP.To4())
   292  		addr.Un.SetIP4(ip4addr)
   293  	}
   294  	mask, _ := dstNetwork.Mask.Size()
   295  	return ip_types.Prefix{
   296  		Address: addr,
   297  		Len:     uint8(mask),
   298  	}
   299  }
   300  
   301  func uintToBool(value uint8) bool {
   302  	return value != 0
   303  }
   304  
   305  func boolToUint(input bool) uint8 {
   306  	if input {
   307  		return 1
   308  	}
   309  	return 0
   310  }