go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/aclplugin/vppcalls/vpp2210/dump_vppcalls.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  	"strings"
    21  
    22  	"go.ligato.io/cn-infra/v2/logging/logrus"
    23  
    24  	"go.ligato.io/vpp-agent/v3/plugins/vpp/aclplugin/vppcalls"
    25  	vpp_acl "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210/acl"
    26  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210/acl_types"
    27  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210/interface_types"
    28  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210/ip_types"
    29  	acl "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/acl"
    30  )
    31  
    32  // DumpACL implements ACL handler.
    33  func (h *ACLVppHandler) DumpACL() ([]*vppcalls.ACLDetails, error) {
    34  	ruleIPData := make(map[vppcalls.ACLMeta][]*acl.ACL_Rule)
    35  
    36  	// get all ACLs with IP ruleData
    37  	IPRuleACLs, err := h.DumpIPAcls()
    38  	if len(IPRuleACLs) < 1 || err != nil {
    39  		return nil, err
    40  	}
    41  
    42  	// resolve IP rules for every ACL
    43  	// Note: currently ACL may have only IP ruleData or only MAC IP ruleData
    44  	var wasErr error
    45  	for identifier, IPRules := range IPRuleACLs {
    46  		var rulesDetails []*acl.ACL_Rule
    47  
    48  		if len(IPRules) > 0 {
    49  			for _, IPRule := range IPRules {
    50  				ruleDetails, err := h.getIPRuleDetails(IPRule)
    51  				if err != nil {
    52  					return nil, fmt.Errorf("failed to get IP Rule %v details: %v", IPRule, err)
    53  				}
    54  				rulesDetails = append(rulesDetails, ruleDetails)
    55  			}
    56  		}
    57  		ruleIPData[identifier] = rulesDetails
    58  	}
    59  
    60  	// Prepare separate list of all active ACL indices on the VPP
    61  	var indices []uint32
    62  	for identifier := range ruleIPData {
    63  		indices = append(indices, identifier.Index)
    64  	}
    65  
    66  	// Get all ACL indices with ingress and egress interfaces
    67  	interfaceData, err := h.DumpACLInterfaces(indices)
    68  	if err != nil {
    69  		return nil, err
    70  	}
    71  
    72  	var ACLs []*vppcalls.ACLDetails
    73  	// Build a list of ACL ruleData with ruleData, interfaces, index and tag (name)
    74  	for identifier, rules := range ruleIPData {
    75  		ACLs = append(ACLs, &vppcalls.ACLDetails{
    76  			ACL: &acl.ACL{
    77  				Name:       identifier.Tag,
    78  				Rules:      rules,
    79  				Interfaces: interfaceData[identifier.Index],
    80  			},
    81  			Meta: &vppcalls.ACLMeta{
    82  				Index: identifier.Index,
    83  				Tag:   identifier.Tag,
    84  			},
    85  		})
    86  	}
    87  
    88  	return ACLs, wasErr
    89  }
    90  
    91  // DumpMACIPACL implements ACL handler.
    92  func (h *ACLVppHandler) DumpMACIPACL() ([]*vppcalls.ACLDetails, error) {
    93  	ruleMACIPData := make(map[vppcalls.ACLMeta][]*acl.ACL_Rule)
    94  
    95  	// get all ACLs with MACIP ruleData
    96  	MACIPRuleACLs, err := h.DumpMacIPAcls()
    97  	if err != nil || len(MACIPRuleACLs) == 0 {
    98  		return nil, err
    99  	}
   100  
   101  	// resolve MACIP rules for every ACL
   102  	for metadata, MACIPRules := range MACIPRuleACLs {
   103  		var rulesDetails []*acl.ACL_Rule
   104  
   105  		for _, MACIPRule := range MACIPRules {
   106  			ruleDetails, err := h.getMACIPRuleDetails(MACIPRule)
   107  			if err != nil {
   108  				return nil, fmt.Errorf("failed to get MACIP Rule %v details: %v", MACIPRule, err)
   109  			}
   110  			rulesDetails = append(rulesDetails, ruleDetails)
   111  		}
   112  		ruleMACIPData[metadata] = rulesDetails
   113  	}
   114  
   115  	// Prepare separate list of all active ACL indices on the VPP
   116  	var indices []uint32
   117  	for identifier := range ruleMACIPData {
   118  		indices = append(indices, identifier.Index)
   119  	}
   120  
   121  	// Get all ACL indices with ingress and egress interfaces
   122  	interfaceData, err := h.DumpMACIPACLInterfaces(indices)
   123  	if err != nil {
   124  		return nil, err
   125  	}
   126  
   127  	var ACLs []*vppcalls.ACLDetails
   128  	// Build a list of ACL ruleData with ruleData, interfaces, index and tag (name)
   129  	for metadata, rules := range ruleMACIPData {
   130  		ACLs = append(ACLs, &vppcalls.ACLDetails{
   131  			ACL: &acl.ACL{
   132  				Name:       metadata.Tag,
   133  				Rules:      rules,
   134  				Interfaces: interfaceData[metadata.Index],
   135  			},
   136  			Meta: &vppcalls.ACLMeta{
   137  				Index: metadata.Index,
   138  				Tag:   metadata.Tag,
   139  			},
   140  		})
   141  	}
   142  	return ACLs, nil
   143  }
   144  
   145  // DumpACLInterfaces implements ACL handler.
   146  func (h *ACLVppHandler) DumpACLInterfaces(indices []uint32) (map[uint32]*acl.ACL_Interfaces, error) {
   147  	// list of ACL-to-interfaces
   148  	aclsWithInterfaces := make(map[uint32]*acl.ACL_Interfaces)
   149  
   150  	var interfaceData []*vppcalls.ACLToInterface
   151  	var wasErr error
   152  
   153  	msgIP := &vpp_acl.ACLInterfaceListDump{
   154  		SwIfIndex: 0xffffffff, // dump all
   155  	}
   156  	reqIP := h.callsChannel.SendMultiRequest(msgIP)
   157  	for {
   158  		replyIP := &vpp_acl.ACLInterfaceListDetails{}
   159  		stop, err := reqIP.ReceiveReply(replyIP)
   160  		if stop {
   161  			break
   162  		}
   163  		if err != nil {
   164  			return aclsWithInterfaces, fmt.Errorf("ACL interface list dump reply error: %v", err)
   165  		}
   166  
   167  		if replyIP.Count > 0 {
   168  			data := &vppcalls.ACLToInterface{
   169  				SwIfIdx: uint32(replyIP.SwIfIndex),
   170  			}
   171  			for i, aclIdx := range replyIP.Acls {
   172  				if i < int(replyIP.NInput) {
   173  					data.IngressACL = append(data.IngressACL, aclIdx)
   174  				} else {
   175  					data.EgressACL = append(data.EgressACL, aclIdx)
   176  				}
   177  			}
   178  			interfaceData = append(interfaceData, data)
   179  		}
   180  	}
   181  
   182  	// sort interfaces for every ACL
   183  	for _, aclIdx := range indices {
   184  		var ingress []string
   185  		var egress []string
   186  		for _, data := range interfaceData {
   187  			// look for ingress
   188  			for _, ingressACLIdx := range data.IngressACL {
   189  				if ingressACLIdx == aclIdx {
   190  					name, _, found := h.ifIndexes.LookupBySwIfIndex(data.SwIfIdx)
   191  					if !found {
   192  						continue
   193  					}
   194  					ingress = append(ingress, name)
   195  				}
   196  			}
   197  			// look for egress
   198  			for _, egressACLIdx := range data.EgressACL {
   199  				if egressACLIdx == aclIdx {
   200  					name, _, found := h.ifIndexes.LookupBySwIfIndex(data.SwIfIdx)
   201  					if !found {
   202  						continue
   203  					}
   204  					egress = append(egress, name)
   205  				}
   206  			}
   207  		}
   208  
   209  		aclsWithInterfaces[aclIdx] = &acl.ACL_Interfaces{
   210  			Egress:  egress,
   211  			Ingress: ingress,
   212  		}
   213  	}
   214  
   215  	return aclsWithInterfaces, wasErr
   216  }
   217  
   218  // DumpMACIPACLInterfaces implements ACL handler.
   219  func (h *ACLVppHandler) DumpMACIPACLInterfaces(indices []uint32) (map[uint32]*acl.ACL_Interfaces, error) {
   220  	// list of ACL-to-interfaces
   221  	aclsWithInterfaces := make(map[uint32]*acl.ACL_Interfaces)
   222  
   223  	var interfaceData []*vppcalls.ACLToInterface
   224  
   225  	msgMACIP := &vpp_acl.MacipACLInterfaceListDump{
   226  		SwIfIndex: 0xffffffff, // dump all
   227  	}
   228  	reqMACIP := h.callsChannel.SendMultiRequest(msgMACIP)
   229  	for {
   230  		replyMACIP := &vpp_acl.MacipACLInterfaceListDetails{}
   231  		stop, err := reqMACIP.ReceiveReply(replyMACIP)
   232  		if stop {
   233  			break
   234  		}
   235  		if err != nil {
   236  			return nil, fmt.Errorf("MACIP ACL interface list dump reply error: %v", err)
   237  		}
   238  		if replyMACIP.Count > 0 {
   239  			data := &vppcalls.ACLToInterface{
   240  				SwIfIdx: uint32(replyMACIP.SwIfIndex),
   241  			}
   242  			data.IngressACL = append(data.IngressACL, replyMACIP.Acls...)
   243  			interfaceData = append(interfaceData, data)
   244  		}
   245  	}
   246  
   247  	for _, aclIdx := range indices {
   248  		var ingress []string
   249  		for _, data := range interfaceData {
   250  			// look for ingress
   251  			for _, ingressACLIdx := range data.IngressACL {
   252  				if ingressACLIdx == aclIdx {
   253  					name, _, found := h.ifIndexes.LookupBySwIfIndex(data.SwIfIdx)
   254  					if !found {
   255  						continue
   256  					}
   257  					ingress = append(ingress, name)
   258  				}
   259  			}
   260  		}
   261  		var ifaces *acl.ACL_Interfaces
   262  		if len(ingress) > 0 {
   263  			ifaces = &acl.ACL_Interfaces{
   264  				Egress:  nil,
   265  				Ingress: ingress,
   266  			}
   267  		}
   268  		aclsWithInterfaces[aclIdx] = ifaces
   269  	}
   270  
   271  	return aclsWithInterfaces, nil
   272  }
   273  
   274  // DumpIPAcls implements ACL handler.
   275  func (h *ACLVppHandler) DumpIPAcls() (map[vppcalls.ACLMeta][]acl_types.ACLRule, error) {
   276  	aclIPRules := make(map[vppcalls.ACLMeta][]acl_types.ACLRule)
   277  	var wasErr error
   278  
   279  	req := &vpp_acl.ACLDump{
   280  		ACLIndex: 0xffffffff,
   281  	}
   282  	reqContext := h.callsChannel.SendMultiRequest(req)
   283  	for {
   284  		msg := &vpp_acl.ACLDetails{}
   285  		stop, err := reqContext.ReceiveReply(msg)
   286  		if err != nil {
   287  			return aclIPRules, fmt.Errorf("ACL dump reply error: %v", err)
   288  		}
   289  		if stop {
   290  			break
   291  		}
   292  
   293  		metadata := vppcalls.ACLMeta{
   294  			Index: msg.ACLIndex,
   295  			Tag:   strings.Trim(msg.Tag, "\x00"),
   296  		}
   297  
   298  		aclIPRules[metadata] = msg.R
   299  	}
   300  
   301  	return aclIPRules, wasErr
   302  }
   303  
   304  // DumpMacIPAcls implements ACL handler.
   305  func (h *ACLVppHandler) DumpMacIPAcls() (map[vppcalls.ACLMeta][]acl_types.MacipACLRule, error) {
   306  	aclMACIPRules := make(map[vppcalls.ACLMeta][]acl_types.MacipACLRule)
   307  
   308  	req := &vpp_acl.MacipACLDump{
   309  		ACLIndex: 0xffffffff,
   310  	}
   311  	reqContext := h.callsChannel.SendMultiRequest(req)
   312  	for {
   313  		msg := &vpp_acl.MacipACLDetails{}
   314  		stop, err := reqContext.ReceiveReply(msg)
   315  		if err != nil {
   316  			return nil, fmt.Errorf("ACL MACIP dump reply error: %v", err)
   317  		}
   318  		if stop {
   319  			break
   320  		}
   321  
   322  		metadata := vppcalls.ACLMeta{
   323  			Index: msg.ACLIndex,
   324  			Tag:   strings.Trim(msg.Tag, "\x00"),
   325  		}
   326  
   327  		aclMACIPRules[metadata] = msg.R
   328  	}
   329  	return aclMACIPRules, nil
   330  }
   331  
   332  // DumpInterfaceACLs implements ACL handler.
   333  func (h *ACLVppHandler) DumpInterfaceACLs(swIndex uint32) (acls []*acl.ACL, err error) {
   334  	res, err := h.DumpInterfaceACLList(swIndex)
   335  	if err != nil {
   336  		return nil, err
   337  	}
   338  
   339  	if uint32(res.SwIfIndex) != swIndex {
   340  		return nil, fmt.Errorf("returned interface index %d does not match request", res.SwIfIndex)
   341  	}
   342  
   343  	for aidx := range res.Acls {
   344  		ipACL, err := h.getIPACLDetails(uint32(aidx))
   345  		if err != nil {
   346  			return nil, err
   347  		}
   348  		acls = append(acls, ipACL)
   349  	}
   350  	return acls, nil
   351  }
   352  
   353  // DumpInterfaceMACIPACLs implements ACL handler.
   354  func (h *ACLVppHandler) DumpInterfaceMACIPACLs(swIndex uint32) (acls []*acl.ACL, err error) {
   355  	resMacIP, err := h.DumpInterfaceMACIPACLList(swIndex)
   356  	if err != nil {
   357  		return nil, err
   358  	}
   359  
   360  	if uint32(resMacIP.SwIfIndex) != swIndex {
   361  		return nil, fmt.Errorf("returned interface index %d does not match request", resMacIP.SwIfIndex)
   362  	}
   363  
   364  	for aidx := range resMacIP.Acls {
   365  		macipACL, err := h.getMACIPACLDetails(uint32(aidx))
   366  		if err != nil {
   367  			return nil, err
   368  		}
   369  		acls = append(acls, macipACL)
   370  	}
   371  	return acls, nil
   372  }
   373  
   374  // DumpInterfaceACLList implements ACL handler.
   375  func (h *ACLVppHandler) DumpInterfaceACLList(swIndex uint32) (*vpp_acl.ACLInterfaceListDetails, error) {
   376  	req := &vpp_acl.ACLInterfaceListDump{
   377  		SwIfIndex: interface_types.InterfaceIndex(swIndex),
   378  	}
   379  	reply := &vpp_acl.ACLInterfaceListDetails{}
   380  
   381  	if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil {
   382  		return nil, err
   383  	}
   384  
   385  	return reply, nil
   386  }
   387  
   388  // DumpInterfaceMACIPACLList implements ACL handler.
   389  func (h *ACLVppHandler) DumpInterfaceMACIPACLList(swIndex uint32) (*vpp_acl.MacipACLInterfaceListDetails, error) {
   390  	req := &vpp_acl.MacipACLInterfaceListDump{
   391  		SwIfIndex: interface_types.InterfaceIndex(swIndex),
   392  	}
   393  	reply := &vpp_acl.MacipACLInterfaceListDetails{}
   394  
   395  	if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil {
   396  		return nil, err
   397  	}
   398  
   399  	return reply, nil
   400  }
   401  
   402  // DumpInterfacesLists implements ACL handler.
   403  func (h *ACLVppHandler) DumpInterfacesLists() ([]*vpp_acl.ACLInterfaceListDetails, []*vpp_acl.MacipACLInterfaceListDetails, error) {
   404  	msgIPACL := &vpp_acl.ACLInterfaceListDump{
   405  		SwIfIndex: 0xffffffff, // dump all
   406  	}
   407  
   408  	reqIPACL := h.callsChannel.SendMultiRequest(msgIPACL)
   409  
   410  	var IPaclInterfaces []*vpp_acl.ACLInterfaceListDetails
   411  	for {
   412  		reply := &vpp_acl.ACLInterfaceListDetails{}
   413  		stop, err := reqIPACL.ReceiveReply(reply)
   414  		if stop {
   415  			break
   416  		}
   417  		if err != nil {
   418  			logrus.DefaultLogger().Error(err)
   419  			return nil, nil, err
   420  		}
   421  		IPaclInterfaces = append(IPaclInterfaces, reply)
   422  	}
   423  
   424  	msgMACIPACL := &vpp_acl.ACLInterfaceListDump{
   425  		SwIfIndex: 0xffffffff, // dump all
   426  	}
   427  
   428  	reqMACIPACL := h.callsChannel.SendMultiRequest(msgMACIPACL)
   429  
   430  	var MACIPaclInterfaces []*vpp_acl.MacipACLInterfaceListDetails
   431  	for {
   432  		reply := &vpp_acl.MacipACLInterfaceListDetails{}
   433  		stop, err := reqMACIPACL.ReceiveReply(reply)
   434  		if stop {
   435  			break
   436  		}
   437  		if err != nil {
   438  			logrus.DefaultLogger().Error(err)
   439  			return nil, nil, err
   440  		}
   441  		MACIPaclInterfaces = append(MACIPaclInterfaces, reply)
   442  	}
   443  
   444  	return IPaclInterfaces, MACIPaclInterfaces, nil
   445  }
   446  
   447  func (h *ACLVppHandler) getIPRuleDetails(rule acl_types.ACLRule) (*acl.ACL_Rule, error) {
   448  	// Resolve rule actions
   449  	aclAction, err := h.resolveRuleAction(rule.IsPermit)
   450  	if err != nil {
   451  		return nil, err
   452  	}
   453  
   454  	return &acl.ACL_Rule{
   455  		Action: aclAction,
   456  		IpRule: h.getIPRuleMatches(rule),
   457  	}, nil
   458  }
   459  
   460  // getIPACLDetails gets details for a given IP ACL from VPP and translates
   461  // them from the binary VPP API format into the ACL Plugin's NB format.
   462  func (h *ACLVppHandler) getIPACLDetails(idx uint32) (aclRule *acl.ACL, err error) {
   463  	req := &vpp_acl.ACLDump{
   464  		ACLIndex: uint32(idx),
   465  	}
   466  
   467  	reply := &vpp_acl.ACLDetails{}
   468  	if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil {
   469  		return nil, err
   470  	}
   471  
   472  	var ruleData []*acl.ACL_Rule
   473  	for _, r := range reply.R {
   474  		rule := &acl.ACL_Rule{}
   475  
   476  		ipRule, err := h.getIPRuleDetails(r)
   477  		if err != nil {
   478  			return nil, err
   479  		}
   480  
   481  		aclAction, err := h.resolveRuleAction(r.IsPermit)
   482  		if err != nil {
   483  			return nil, err
   484  		}
   485  
   486  		rule.IpRule = ipRule.GetIpRule()
   487  		rule.Action = aclAction
   488  		ruleData = append(ruleData, rule)
   489  	}
   490  
   491  	return &acl.ACL{Rules: ruleData, Name: strings.Trim(reply.Tag, "\x00")}, nil
   492  }
   493  
   494  func (h *ACLVppHandler) getMACIPRuleDetails(rule acl_types.MacipACLRule) (*acl.ACL_Rule, error) {
   495  	// Resolve rule actions
   496  	aclAction, err := h.resolveRuleAction(rule.IsPermit)
   497  	if err != nil {
   498  		return nil, err
   499  	}
   500  
   501  	return &acl.ACL_Rule{
   502  		Action:    aclAction,
   503  		MacipRule: h.getMACIPRuleMatches(rule),
   504  	}, nil
   505  }
   506  
   507  // getMACIPACLDetails gets details for a given MACIP ACL from VPP and translates
   508  // them from the binary VPP API format into the ACL Plugin's NB format.
   509  func (h *ACLVppHandler) getMACIPACLDetails(idx uint32) (aclRule *acl.ACL, err error) {
   510  	req := &vpp_acl.MacipACLDump{
   511  		ACLIndex: uint32(idx),
   512  	}
   513  
   514  	reply := &vpp_acl.MacipACLDetails{}
   515  	if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil {
   516  		return nil, err
   517  	}
   518  
   519  	var ruleData []*acl.ACL_Rule
   520  	for _, r := range reply.R {
   521  		rule := &acl.ACL_Rule{}
   522  
   523  		ipRule, err := h.getMACIPRuleDetails(r)
   524  		if err != nil {
   525  			return nil, err
   526  		}
   527  
   528  		aclAction, err := h.resolveRuleAction(r.IsPermit)
   529  		if err != nil {
   530  			return nil, err
   531  		}
   532  
   533  		rule.IpRule = ipRule.GetIpRule()
   534  		rule.Action = aclAction
   535  		ruleData = append(ruleData, rule)
   536  	}
   537  
   538  	return &acl.ACL{Rules: ruleData, Name: strings.Trim(reply.Tag, "\x00")}, nil
   539  }
   540  
   541  // getIPRuleMatches translates an IP rule from the binary VPP API format into the
   542  // ACL Plugin's NB format
   543  func (h *ACLVppHandler) getIPRuleMatches(r acl_types.ACLRule) *acl.ACL_Rule_IpRule {
   544  	srcNet := prefixToString(r.SrcPrefix)
   545  	dstNet := prefixToString(r.DstPrefix)
   546  
   547  	ipRule := &acl.ACL_Rule_IpRule{
   548  		Ip: &acl.ACL_Rule_IpRule_Ip{
   549  			SourceNetwork:      srcNet,
   550  			DestinationNetwork: dstNet,
   551  			Protocol:           uint32(r.Proto),
   552  		},
   553  	}
   554  
   555  	switch r.Proto {
   556  	case vppcalls.TCPProto:
   557  		ipRule.Tcp = h.getTCPMatchRule(r)
   558  	case vppcalls.UDPProto:
   559  		ipRule.Udp = h.getUDPMatchRule(r)
   560  	case vppcalls.ICMPv4Proto, vppcalls.ICMPv6Proto:
   561  		ipRule.Icmp = h.getIcmpMatchRule(r)
   562  	}
   563  	return ipRule
   564  }
   565  
   566  // getMACIPRuleMatches translates an MACIP rule from the binary VPP API format into the
   567  // ACL Plugin's NB format
   568  func (h *ACLVppHandler) getMACIPRuleMatches(rule acl_types.MacipACLRule) *acl.ACL_Rule_MacIpRule {
   569  	srcAddr := addressToIP(rule.SrcPrefix.Address)
   570  	srcMacAddr := net.HardwareAddr(rule.SrcMac[:])
   571  	srcMacAddrMask := net.HardwareAddr(rule.SrcMacMask[:])
   572  	return &acl.ACL_Rule_MacIpRule{
   573  		SourceAddress:        srcAddr.String(),
   574  		SourceAddressPrefix:  uint32(rule.SrcPrefix.Len),
   575  		SourceMacAddress:     srcMacAddr.String(),
   576  		SourceMacAddressMask: srcMacAddrMask.String(),
   577  	}
   578  }
   579  
   580  // getTCPMatchRule translates a TCP match rule from the binary VPP API format
   581  // into the ACL Plugin's NB format
   582  func (h *ACLVppHandler) getTCPMatchRule(r acl_types.ACLRule) *acl.ACL_Rule_IpRule_Tcp {
   583  	dstPortRange := &acl.ACL_Rule_IpRule_PortRange{
   584  		LowerPort: uint32(r.DstportOrIcmpcodeFirst),
   585  		UpperPort: uint32(r.DstportOrIcmpcodeLast),
   586  	}
   587  	srcPortRange := &acl.ACL_Rule_IpRule_PortRange{
   588  		LowerPort: uint32(r.SrcportOrIcmptypeFirst),
   589  		UpperPort: uint32(r.SrcportOrIcmptypeLast),
   590  	}
   591  	tcp := acl.ACL_Rule_IpRule_Tcp{
   592  		DestinationPortRange: dstPortRange,
   593  		SourcePortRange:      srcPortRange,
   594  		TcpFlagsMask:         uint32(r.TCPFlagsMask),
   595  		TcpFlagsValue:        uint32(r.TCPFlagsValue),
   596  	}
   597  	return &tcp
   598  }
   599  
   600  // getUDPMatchRule translates a UDP match rule from the binary VPP API format
   601  // into the ACL Plugin's NB format
   602  func (h *ACLVppHandler) getUDPMatchRule(r acl_types.ACLRule) *acl.ACL_Rule_IpRule_Udp {
   603  	dstPortRange := &acl.ACL_Rule_IpRule_PortRange{
   604  		LowerPort: uint32(r.DstportOrIcmpcodeFirst),
   605  		UpperPort: uint32(r.DstportOrIcmpcodeLast),
   606  	}
   607  	srcPortRange := &acl.ACL_Rule_IpRule_PortRange{
   608  		LowerPort: uint32(r.SrcportOrIcmptypeFirst),
   609  		UpperPort: uint32(r.SrcportOrIcmptypeLast),
   610  	}
   611  	udp := acl.ACL_Rule_IpRule_Udp{
   612  		DestinationPortRange: dstPortRange,
   613  		SourcePortRange:      srcPortRange,
   614  	}
   615  	return &udp
   616  }
   617  
   618  // getIcmpMatchRule translates an ICMP match rule from the binary VPP API
   619  // format into the ACL Plugin's NB format
   620  func (h *ACLVppHandler) getIcmpMatchRule(r acl_types.ACLRule) *acl.ACL_Rule_IpRule_Icmp {
   621  	icmp := &acl.ACL_Rule_IpRule_Icmp{
   622  		Icmpv6: r.Proto == ip_types.IP_API_PROTO_ICMP6,
   623  		IcmpCodeRange: &acl.ACL_Rule_IpRule_Icmp_Range{
   624  			First: uint32(r.DstportOrIcmpcodeFirst),
   625  			Last:  uint32(r.DstportOrIcmpcodeLast),
   626  		},
   627  		IcmpTypeRange: &acl.ACL_Rule_IpRule_Icmp_Range{
   628  			First: uint32(r.SrcportOrIcmptypeFirst),
   629  			Last:  uint32(r.SrcportOrIcmptypeLast),
   630  		},
   631  	}
   632  	return icmp
   633  }
   634  
   635  // Returns rule action representation in model according to the vpp input
   636  func (h *ACLVppHandler) resolveRuleAction(isPermit acl_types.ACLAction) (acl.ACL_Rule_Action, error) {
   637  	switch isPermit {
   638  	case acl_types.ACL_ACTION_API_DENY:
   639  		return acl.ACL_Rule_DENY, nil
   640  	case acl_types.ACL_ACTION_API_PERMIT:
   641  		return acl.ACL_Rule_PERMIT, nil
   642  	case acl_types.ACL_ACTION_API_PERMIT_REFLECT:
   643  		return acl.ACL_Rule_REFLECT, nil
   644  	default:
   645  		return acl.ACL_Rule_DENY, fmt.Errorf("invalid match rule %v", isPermit)
   646  	}
   647  }