go.ligato.io/vpp-agent/v3@v3.5.0/tests/integration/vpp/040_acl_test.go (about)

     1  //  Copyright (c) 2021 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 vpp
    16  
    17  import (
    18  	"strings"
    19  	"testing"
    20  
    21  	. "github.com/onsi/gomega"
    22  	"go.ligato.io/cn-infra/v2/logging/logrus"
    23  
    24  	aclplugin_vppcalls "go.ligato.io/vpp-agent/v3/plugins/vpp/aclplugin/vppcalls"
    25  	"go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/ifaceidx"
    26  	ifplugin_vppcalls "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/vppcalls"
    27  	acl "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/acl"
    28  
    29  	_ "go.ligato.io/vpp-agent/v3/plugins/vpp/aclplugin"
    30  	_ "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin"
    31  )
    32  
    33  func rulePerm(permit bool) acl.ACL_Rule_Action {
    34  	var aclRulePerm acl.ACL_Rule_Action
    35  
    36  	if permit {
    37  		aclRulePerm = acl.ACL_Rule_PERMIT
    38  	} else {
    39  		aclRulePerm = acl.ACL_Rule_DENY
    40  	}
    41  
    42  	return aclRulePerm
    43  }
    44  
    45  // helper function which returns ACL_Rule (to avoid of declarating variable)
    46  func newACLIPRule(permit bool, src, dst string) *acl.ACL_Rule {
    47  	return &acl.ACL_Rule{
    48  		Action: rulePerm(permit),
    49  		IpRule: &acl.ACL_Rule_IpRule{
    50  			Ip: &acl.ACL_Rule_IpRule_Ip{
    51  				SourceNetwork:      src,
    52  				DestinationNetwork: dst,
    53  			},
    54  		},
    55  	}
    56  }
    57  
    58  // helper function which returns ACL_Rule (to avoid of declarating variable)
    59  func newACLIPRuleWithProto(permit bool, src, dst string, proto uint32) *acl.ACL_Rule {
    60  	return &acl.ACL_Rule{
    61  		Action: rulePerm(permit),
    62  		IpRule: &acl.ACL_Rule_IpRule{
    63  			Ip: &acl.ACL_Rule_IpRule_Ip{
    64  				SourceNetwork:      src,
    65  				DestinationNetwork: dst,
    66  				Protocol:           proto,
    67  			},
    68  		},
    69  	}
    70  }
    71  
    72  // helper function which returns ACL_Rule (to avoid of declarating variable)
    73  func newACLIPRuleIcmp(permit, isicmpv6 bool, codefrom, codeto, typefrom, typeto uint32) *acl.ACL_Rule {
    74  	return &acl.ACL_Rule{
    75  		Action: rulePerm(permit),
    76  		IpRule: &acl.ACL_Rule_IpRule{
    77  			Icmp: &acl.ACL_Rule_IpRule_Icmp{
    78  				Icmpv6: isicmpv6,
    79  				IcmpCodeRange: &acl.ACL_Rule_IpRule_Icmp_Range{
    80  					First: codefrom,
    81  					Last:  codeto,
    82  				},
    83  				IcmpTypeRange: &acl.ACL_Rule_IpRule_Icmp_Range{
    84  					First: typefrom,
    85  					Last:  typeto,
    86  				},
    87  			},
    88  		},
    89  	}
    90  }
    91  
    92  // helper function which returns ACL_Rule (to avoid of declarating variable)
    93  func newACLIPRuleTCP(permit bool, flagsval, flagsmask, srcportfrom, srcportto, destportfrom, destportto uint32) *acl.ACL_Rule {
    94  	return &acl.ACL_Rule{
    95  		Action: rulePerm(permit),
    96  		IpRule: &acl.ACL_Rule_IpRule{
    97  			Tcp: &acl.ACL_Rule_IpRule_Tcp{
    98  				TcpFlagsMask:  flagsmask,
    99  				TcpFlagsValue: flagsval,
   100  				SourcePortRange: &acl.ACL_Rule_IpRule_PortRange{
   101  					LowerPort: srcportfrom,
   102  					UpperPort: srcportto,
   103  				},
   104  				DestinationPortRange: &acl.ACL_Rule_IpRule_PortRange{
   105  					LowerPort: destportfrom,
   106  					UpperPort: destportto,
   107  				},
   108  			},
   109  		},
   110  	}
   111  }
   112  
   113  // helper function which returns ACL_Rule (to avoid of declarating variable)
   114  func newACLIPRuleUDP(permit bool, srcportfrom, srcportto, destportfrom, destportto uint32) *acl.ACL_Rule {
   115  	return &acl.ACL_Rule{
   116  		Action: rulePerm(permit),
   117  		IpRule: &acl.ACL_Rule_IpRule{
   118  			Udp: &acl.ACL_Rule_IpRule_Udp{
   119  				SourcePortRange: &acl.ACL_Rule_IpRule_PortRange{
   120  					LowerPort: srcportfrom,
   121  					UpperPort: srcportto,
   122  				},
   123  				DestinationPortRange: &acl.ACL_Rule_IpRule_PortRange{
   124  					LowerPort: destportfrom,
   125  					UpperPort: destportto,
   126  				},
   127  			},
   128  		},
   129  	}
   130  }
   131  
   132  // helper function which returns ACL_Rule (to avoid of declarating variable)
   133  func newACLMacIPRule(permit bool, src string, srcPrefix uint32, srcMacAddr string, srcMacMask string) *acl.ACL_Rule {
   134  	return &acl.ACL_Rule{
   135  		Action: rulePerm(permit),
   136  		MacipRule: &acl.ACL_Rule_MacIpRule{
   137  			SourceAddress:        src,
   138  			SourceAddressPrefix:  srcPrefix,
   139  			SourceMacAddress:     srcMacAddr,
   140  			SourceMacAddressMask: srcMacMask,
   141  		},
   142  	}
   143  }
   144  
   145  func TestCRUDIPAcl(t *testing.T) {
   146  	ctx := setupVPP(t)
   147  	defer ctx.teardownVPP()
   148  
   149  	ih := ifplugin_vppcalls.CompatibleInterfaceVppHandler(ctx.vppClient, logrus.NewLogger("test"))
   150  	Expect(ih).To(Not(BeNil()), "Handler should be created.")
   151  
   152  	const ifName = "loop1"
   153  	ifIdx, errI := ih.AddLoopbackInterface(ifName)
   154  	Expect(errI).To(BeNil())
   155  	t.Logf("Prerequsite: interface %v created - its index %v", ifName, ifIdx)
   156  
   157  	const ifName2 = "loop2"
   158  	ifIdx2, errI2 := ih.AddLoopbackInterface(ifName2)
   159  	Expect(errI2).To(BeNil())
   160  	t.Logf("Prerequsite: interface %v created - its index %v", ifName2, ifIdx2)
   161  
   162  	ifIndexes := ifaceidx.NewIfaceIndex(logrus.NewLogger("test-iface1"), "test-iface1")
   163  	ifIndexes.Put(ifName, &ifaceidx.IfaceMetadata{
   164  		SwIfIndex: ifIdx,
   165  	})
   166  	ifIndexes.Put(ifName2, &ifaceidx.IfaceMetadata{
   167  		SwIfIndex: ifIdx2,
   168  	})
   169  
   170  	h := aclplugin_vppcalls.CompatibleACLHandler(ctx.vppClient, ifIndexes)
   171  	Expect(h).To(Not(BeNil()), "Handler should be created.")
   172  
   173  	acls, errx := h.DumpACL()
   174  	Expect(errx).To(BeNil())
   175  	Expect(acls).Should(BeEmpty())
   176  	t.Log("no acls dumped")
   177  
   178  	const aclname = "test0"
   179  	const ospf = 89
   180  	aclIdx, err := h.AddACL([]*acl.ACL_Rule{
   181  		//RuleName:  "permitIPv4",
   182  		newACLIPRule(true, "192.168.1.1/32", "10.20.0.0/24"),
   183  		//RuleName:  "permitIPv6",
   184  		newACLIPRule(true, "dead::1/64", "dead::2/64"),
   185  		//RuleName:  "denyICMP",
   186  		newACLIPRuleIcmp(false, false, 10, 20, 30, 40),
   187  		//RuleName:  "denyICMPv6",
   188  		newACLIPRuleIcmp(false, true, 10, 20, 30, 40),
   189  		//RuleName:  "permitTCP",
   190  		newACLIPRuleTCP(true, 10, 20, 150, 250, 1150, 1250),
   191  		//RuleName:  "denyUDP",
   192  		newACLIPRuleUDP(false, 150, 250, 1150, 1250),
   193  		// deny OSPF
   194  		newACLIPRuleWithProto(false, "0.0.0.0/0", "0.0.0.0/0", ospf),
   195  	}, aclname)
   196  	Expect(err).To(BeNil())
   197  	Expect(aclIdx).To(BeEquivalentTo(0))
   198  	t.Logf("acl \"%v\" added - its index %d", aclname, aclIdx)
   199  
   200  	err = h.SetACLToInterfacesAsIngress(aclIdx, []uint32{ifIdx})
   201  	Expect(err).To(BeNil())
   202  	t.Logf("acl with index %d was assigned to interface %v ingress", aclIdx, ifName)
   203  
   204  	acls, errx = h.DumpACL()
   205  	Expect(errx).To(BeNil())
   206  	Expect(acls).Should(HaveLen(1))
   207  	t.Log("amount of acls dumped: 1")
   208  
   209  	var rules []*acl.ACL_Rule
   210  	var isIPRulePresent, isICMPRulePresent, isICMP6RulePresent, isOSPFRulePresent, isForInterface bool
   211  	for _, item := range acls {
   212  		rules = item.ACL.Rules
   213  		if (item.Meta.Index == aclIdx) && (aclname == item.Meta.Tag) {
   214  			t.Logf("found ACL \"%v\"", item.Meta.Tag)
   215  			for _, rule := range rules {
   216  				t.Logf("%+v", rule)
   217  				//here maybe all rules should be checked
   218  				if (rule.IpRule.GetIp().SourceNetwork == "192.168.1.1/32") &&
   219  					(rule.IpRule.GetIp().DestinationNetwork == "10.20.0.0/24") {
   220  					isIPRulePresent = true
   221  				}
   222  				if (rule.IpRule.GetIcmp().GetIcmpCodeRange().GetFirst() == 10) &&
   223  					(rule.IpRule.GetIcmp().GetIcmpCodeRange().GetLast() == 20) &&
   224  					(rule.IpRule.GetIcmp().GetIcmpTypeRange().GetFirst() == 30) &&
   225  					(rule.IpRule.GetIcmp().GetIcmpTypeRange().GetLast() == 40) {
   226  					if rule.IpRule.GetIcmp().GetIcmpv6() {
   227  						isICMP6RulePresent = true
   228  					} else {
   229  						isICMPRulePresent = true
   230  					}
   231  				}
   232  				if rule.IpRule.GetIp().GetSourceNetwork() == "0.0.0.0/0" &&
   233  					rule.IpRule.GetIp().GetDestinationNetwork() == "0.0.0.0/0" &&
   234  					rule.IpRule.GetIp().GetProtocol() == ospf {
   235  					isOSPFRulePresent = true
   236  				}
   237  			}
   238  
   239  			// check assignation to interface
   240  			for _, intf := range item.ACL.Interfaces.Ingress {
   241  				if intf == ifName {
   242  					isForInterface = true
   243  					break
   244  				}
   245  			}
   246  		}
   247  	}
   248  	Expect(isIPRulePresent).To(BeTrue(), "Configured IP rule should be present")
   249  	Expect(isICMPRulePresent).To(BeTrue(), "Configured ICMP rule should be present")
   250  	Expect(isICMP6RulePresent).To(BeTrue(), "Configured ICMPv6 rule should be present")
   251  	Expect(isOSPFRulePresent).To(BeTrue(), "Configured OSPF rule should be present")
   252  	Expect(isForInterface).To(BeTrue(), "acl should be assigned to interface")
   253  
   254  	indexes := []uint32{ifIdx, ifIdx2}
   255  	ifaces, errI3 := h.DumpACLInterfaces(indexes)
   256  	Expect(errI3).To(Succeed())
   257  	Expect(ifaces).To(HaveLen(2))
   258  	t.Logf("%v", ifaces)
   259  	t.Logf("%v", ifaces[1])
   260  	t.Logf("%v", ifaces[2])
   261  	//this does not work for VPP 19.04 and maybe also other version
   262  	//checked for VPP 22.02 - still does not work
   263  	//Expect(ifaces[0].Ingress).To(Equal([]string{ifName}))
   264  	//Expect(ifaces[2].Egress).To(Equal([]string{ifName2}))
   265  
   266  	//negative tests - it is expected failure
   267  	t.Logf("Let us test some negative cases....")
   268  	_, err = h.AddACL([]*acl.ACL_Rule{}, "test1")
   269  	Expect(err).To(Not(BeNil()))
   270  	t.Logf("adding acls failed: %v", err)
   271  
   272  	_, err = h.AddACL([]*acl.ACL_Rule{newACLIPRule(true, ".0.", "10.20.0.0/24")}, "test2")
   273  	Expect(err).To(Not(BeNil()))
   274  	t.Logf("adding acls failed: %v", err)
   275  
   276  	_, err = h.AddACL([]*acl.ACL_Rule{newACLIPRule(true, "192.168.1.1/32", ".0.")}, "test3")
   277  	Expect(err).To(Not(BeNil()))
   278  	t.Logf("adding acls failed: %v", err)
   279  
   280  	_, err = h.AddACL([]*acl.ACL_Rule{newACLIPRule(true, "192.168.1.1/32", "dead::1/64")}, "test4")
   281  	Expect(err).To(Not(BeNil()))
   282  	t.Logf("adding acls failed: %v", err)
   283  
   284  	_, err = h.AddACL([]*acl.ACL_Rule{newACLIPRule(true, "", "")}, "test4")
   285  	Expect(err).To(Not(BeNil()))
   286  	t.Logf("adding acls failed: %v", err)
   287  
   288  	//add the same acls again but it will be assigned to the second interface
   289  	t.Log("Now let us add the second acl to the second interface")
   290  	const aclname2 = "test5"
   291  	aclIdx, err = h.AddACL([]*acl.ACL_Rule{
   292  		//RuleName:  "permitIPv4",
   293  		newACLIPRule(true, "192.168.1.1/32", "10.20.0.0/24"),
   294  		//RuleName:  "permitIPv6",
   295  		newACLIPRule(true, "dead::1/64", "dead::2/64"),
   296  		//RuleName:  "denyICMP",
   297  		newACLIPRuleIcmp(false, false, 11, 21, 31, 41),
   298  		//RuleName:  "denyICMPv6",
   299  		newACLIPRuleIcmp(false, true, 11, 21, 31, 41),
   300  		//RuleName:  "permitTCP",
   301  		newACLIPRuleTCP(true, 10, 20, 150, 250, 1150, 1250),
   302  		//RuleName:  "denyUDP",
   303  		newACLIPRuleUDP(false, 150, 250, 1150, 1250),
   304  	}, aclname2)
   305  
   306  	Expect(err).To(BeNil())
   307  	Expect(aclIdx).To(BeEquivalentTo(1))
   308  	t.Logf("acl \"%v\" added - its index %d", aclname2, aclIdx)
   309  
   310  	err = h.SetACLToInterfacesAsEgress(aclIdx, []uint32{ifIdx2})
   311  	Expect(err).To(BeNil())
   312  	t.Logf("acl with index %d was assigned to interface %v egress", aclIdx, ifName2)
   313  
   314  	acls, errx = h.DumpACL()
   315  	Expect(errx).To(BeNil())
   316  	Expect(acls).Should(HaveLen(2))
   317  	t.Log("amount of acls dumped: 2")
   318  
   319  	isIPRulePresent = false
   320  	isICMPRulePresent = false
   321  	isICMP6RulePresent = false
   322  	isForInterface = false
   323  	for _, item := range acls {
   324  		rules = item.ACL.Rules
   325  		if (item.Meta.Index == aclIdx) && (aclname2 == item.Meta.Tag) {
   326  			t.Logf("found ACL \"%v\"", item.Meta.Tag)
   327  			for _, rule := range rules {
   328  				//t.Logf("%+v", rule)
   329  				if (rule.IpRule.GetIp().SourceNetwork == "192.168.1.1/32") &&
   330  					(rule.IpRule.GetIp().DestinationNetwork == "10.20.0.0/24") {
   331  					isIPRulePresent = true
   332  				}
   333  				if (rule.IpRule.GetIcmp().GetIcmpCodeRange().GetFirst() == 11) &&
   334  					(rule.IpRule.GetIcmp().GetIcmpCodeRange().GetLast() == 21) &&
   335  					(rule.IpRule.GetIcmp().GetIcmpTypeRange().GetFirst() == 31) &&
   336  					(rule.IpRule.GetIcmp().GetIcmpTypeRange().GetLast() == 41) {
   337  					if rule.IpRule.GetIcmp().GetIcmpv6() {
   338  						isICMP6RulePresent = true
   339  					} else {
   340  						isICMPRulePresent = true
   341  					}
   342  				}
   343  			}
   344  			// check assignation to interface
   345  			for _, intf := range item.ACL.Interfaces.Egress {
   346  				if intf == ifName2 {
   347  					isForInterface = true
   348  					break
   349  				}
   350  			}
   351  		}
   352  	}
   353  	Expect(isIPRulePresent).To(BeTrue(), "Configured IP should be present")
   354  	Expect(isICMPRulePresent).To(BeTrue(), "Configured ICMP rule should be present")
   355  	Expect(isICMP6RulePresent).To(BeTrue(), "Configured ICMPv6 rule should be present")
   356  	Expect(isForInterface).To(BeTrue(), "acl should be assigned to interface")
   357  
   358  	//negative tests
   359  	err = h.DeleteACL(5)
   360  	Expect(err).To(Not(BeNil()))
   361  	t.Logf("deleting acls failed: %v", err)
   362  
   363  	// find the acl with aclname test0
   364  	var foundaclidx uint32
   365  	for _, item := range acls {
   366  		if aclname == item.Meta.Tag {
   367  			foundaclidx = item.Meta.Index
   368  			break
   369  		}
   370  	}
   371  	err = h.DeleteACL(foundaclidx)
   372  	Expect(err).To(Not(BeNil()))
   373  	t.Logf("deleting of acl \"%v\" failed: %v", aclname, err)
   374  
   375  	// DELETE ACL
   376  	err = h.RemoveACLFromInterfacesAsIngress(foundaclidx, []uint32{ifIdx})
   377  	Expect(err).To(BeNil())
   378  	t.Logf("removing acl \"%v\" from interface with index %d succeed", aclname, ifIdx)
   379  	err = h.DeleteACL(foundaclidx)
   380  	Expect(err).To(BeNil())
   381  	t.Logf("deleting of acl \"%v\" succeed", aclname)
   382  
   383  	acls, errx = h.DumpACL()
   384  	Expect(errx).To(BeNil())
   385  	Expect(acls).Should(HaveLen(1))
   386  	t.Log("amount of acls dumped: 1")
   387  
   388  	for _, aclrecord := range acls {
   389  		if aclrecord.Meta.Index == foundaclidx {
   390  			t.Fatalf("This acll should be deleted : %v", errx)
   391  		}
   392  	}
   393  
   394  	// MODIFY ACL
   395  	rule2modify := []*acl.ACL_Rule{
   396  		newACLIPRule(true, "10.20.30.1/32", "10.20.0.0/24"),
   397  		newACLIPRule(true, "dead:dead::3/64", "dead:dead::4/64"),
   398  		newACLIPRuleIcmp(true, false, 15, 25, 35, 45),
   399  	}
   400  
   401  	const aclname4 = "test_modify0"
   402  	err = h.ModifyACL(1, rule2modify, aclname4)
   403  	Expect(err).To(BeNil())
   404  	t.Logf("modifying of acl with index 1 succeed - the new name of acl is  \"%v\"", aclname4)
   405  
   406  	acls, errx = h.DumpACL()
   407  	Expect(errx).To(BeNil())
   408  	Expect(acls).Should(HaveLen(1))
   409  	t.Log("amount of acls dumped: 1")
   410  
   411  	isIPRulePresent = false
   412  	isICMPRulePresent = false
   413  	isForInterface = false
   414  	var modifiedacl aclplugin_vppcalls.ACLDetails
   415  	for _, item := range acls {
   416  		modifiedacl = *item
   417  		rules = item.ACL.Rules
   418  		if item.Meta.Index == aclIdx && (aclname4 == item.Meta.Tag) {
   419  			t.Logf("Found modified ACL \"%v\"", item.Meta.Tag)
   420  			for _, rule := range rules {
   421  				//t.Logf("%+v", rule)
   422  				if (rule.IpRule.GetIp().SourceNetwork == "192.168.1.1/32") &&
   423  					(rule.IpRule.GetIp().DestinationNetwork == "10.20.0.0/24") {
   424  					t.Fatal("Old rules should not be present")
   425  				}
   426  				//here maybe should be checked all rules
   427  				if (rule.IpRule.GetIp().SourceNetwork == "10.20.30.1/32") &&
   428  					(rule.IpRule.GetIp().DestinationNetwork == "10.20.0.0/24") {
   429  					isIPRulePresent = true
   430  				}
   431  				if (rule.IpRule.GetIcmp().GetIcmpCodeRange().GetFirst() == 15) &&
   432  					(rule.IpRule.GetIcmp().GetIcmpCodeRange().GetLast() == 25) &&
   433  					(rule.IpRule.GetIcmp().GetIcmpTypeRange().GetFirst() == 35) &&
   434  					(rule.IpRule.GetIcmp().GetIcmpTypeRange().GetLast() == 45) {
   435  					if !rule.IpRule.GetIcmp().GetIcmpv6() {
   436  						isICMPRulePresent = true
   437  					}
   438  				}
   439  			}
   440  			// check assignation to interface
   441  			for _, intf := range item.ACL.Interfaces.Egress {
   442  				if intf == ifName2 {
   443  					isForInterface = true
   444  					break
   445  				}
   446  			}
   447  		}
   448  	}
   449  	Expect(isIPRulePresent).To(BeTrue(), "Configured IP should be present")
   450  	Expect(isICMPRulePresent).To(BeTrue(), "Configured ICMP rule should be present")
   451  	Expect(isForInterface).To(BeTrue(), "acl should be assigned to interface")
   452  
   453  	// negative test
   454  	err = h.ModifyACL(1, []*acl.ACL_Rule{newACLIPRule(true, ".0.", "10.20.0.0/24")}, "test_modify1")
   455  	Expect(err).To(Not(BeNil()))
   456  	t.Logf("modifying of acl failed: %v", err)
   457  
   458  	const aclname3 = "test_modify2"
   459  	err = h.ModifyACL(1, []*acl.ACL_Rule{}, aclname3)
   460  	Expect(err).To(BeNil())
   461  	t.Logf("acl with index 1 was modified by empty ACL definition")
   462  
   463  	acls, errx = h.DumpACL()
   464  	Expect(errx).To(BeNil())
   465  	Expect(acls).Should(HaveLen(1))
   466  	t.Log("amount of acls dumped: 1")
   467  
   468  	for _, item := range acls {
   469  		if item.Meta.Index == aclIdx && (aclname4 == item.Meta.Tag) {
   470  			t.Logf("Found modified ACL \"%v\"", item.Meta.Tag)
   471  			Expect(item.ACL.String()).To(Equal(modifiedacl.ACL.String()), "Last update should not cause any change in acl definition.")
   472  			break
   473  		}
   474  	}
   475  	t.Logf("found no change in definition of acl \"%v\" after trying to modify by empty acl definition", aclname4)
   476  
   477  	// DELETE ACL
   478  	err = h.RemoveACLFromInterfacesAsEgress(aclIdx, []uint32{ifIdx2})
   479  	Expect(err).To(BeNil())
   480  	t.Log("removing acl from interface succeed")
   481  
   482  	acls, errx = h.DumpACL()
   483  	Expect(errx).To(BeNil())
   484  	Expect(acls).Should(HaveLen(1))
   485  	t.Log("amount of acls dumped: 1")
   486  
   487  	for _, item := range acls {
   488  		if item.Meta.Index == aclIdx { //&& (aclname2 == item.Meta.Tag) {
   489  			t.Logf("Found modified ACL \"%v\"", item.Meta.Tag)
   490  			Expect(item.ACL.Interfaces.String()).Should(BeEmpty(), "Interface assignment should be removed")
   491  			break
   492  		}
   493  	}
   494  
   495  	err = h.DeleteACL(aclIdx)
   496  	Expect(err).To(BeNil())
   497  	t.Logf("deleting acl succeed")
   498  
   499  	acls, errx = h.DumpACL()
   500  	Expect(errx).To(BeNil())
   501  	Expect(acls).Should(BeEmpty())
   502  	t.Log("no acls dumped")
   503  }
   504  
   505  // Test add MACIP acl rules
   506  func TestCRUDMacIPAcl(t *testing.T) {
   507  	ctx := setupVPP(t)
   508  	defer ctx.teardownVPP()
   509  
   510  	ih := ifplugin_vppcalls.CompatibleInterfaceVppHandler(ctx.vppClient, logrus.NewLogger("test"))
   511  	Expect(ih).To(Not(BeNil()), "Handler should be created.")
   512  
   513  	const ifName = "loop1"
   514  	ifIdx, errI := ih.AddLoopbackInterface(ifName)
   515  	Expect(errI).To(BeNil())
   516  	t.Logf("Prerequsite: interface %v created - its index %v", ifName, ifIdx)
   517  
   518  	const ifName2 = "loop2"
   519  	ifIdx2, errI2 := ih.AddLoopbackInterface(ifName2)
   520  	Expect(errI2).To(BeNil())
   521  	t.Logf("Prerequsite: interface %v created - its index %v", ifName2, ifIdx2)
   522  
   523  	ifIndexes := ifaceidx.NewIfaceIndex(logrus.NewLogger("test-iface1"), "test-iface1")
   524  	ifIndexes.Put(ifName, &ifaceidx.IfaceMetadata{
   525  		SwIfIndex: ifIdx,
   526  	})
   527  	ifIndexes.Put(ifName2, &ifaceidx.IfaceMetadata{
   528  		SwIfIndex: ifIdx2,
   529  	})
   530  
   531  	h := aclplugin_vppcalls.CompatibleACLHandler(ctx.vppClient, ifIndexes)
   532  	Expect(h).To(Not(BeNil()), "Handler should be created.")
   533  	if h == nil {
   534  		t.Fatalf("handler was not created")
   535  	}
   536  
   537  	acls, errx := h.DumpMACIPACL()
   538  	Expect(errx).To(BeNil())
   539  	Expect(acls).Should(BeEmpty(), "no acls expected in dump")
   540  
   541  	const aclname = "test6"
   542  	addRules := []*acl.ACL_Rule{
   543  		//RuleName:  "denyIPv4",
   544  		newACLMacIPRule(false, "192.168.0.1", 16, "11:44:0A:B8:4A:35", "ff:ff:ff:ff:00:00"),
   545  		//RuleName:  "denyIPv6",
   546  		newACLMacIPRule(false, "dead::1", 64, "11:44:0A:B8:4A:35", "ff:ff:ff:ff:00:00"),
   547  	}
   548  	t.Logf("adding %d MACIP acl rules: %v", len(addRules), addRules)
   549  	aclIdx, err := h.AddMACIPACL(addRules, aclname)
   550  	Expect(err).To(BeNil())
   551  	Expect(aclIdx).To(BeEquivalentTo(0))
   552  	t.Logf("acl %q (index: %d) was added", aclname, aclIdx)
   553  
   554  	err = h.SetMACIPACLToInterfaces(aclIdx, []uint32{ifIdx})
   555  	Expect(err).To(BeNil())
   556  	t.Logf("acl %q (index: %d) was assigned to interface %v", aclname, aclIdx, ifName)
   557  
   558  	acls, errx = h.DumpMACIPACL()
   559  	Expect(errx).To(BeNil())
   560  	Expect(acls).Should(HaveLen(1), "one acl expected in dump")
   561  
   562  	var rules []*acl.ACL_Rule
   563  	var isPresent bool
   564  	var isForInterface bool
   565  	for _, item := range acls {
   566  		rules = item.ACL.Rules
   567  		if (item.Meta.Index == aclIdx) && (aclname == item.Meta.Tag) {
   568  			t.Logf("found ACL \"%v\" (index: %d)", item.Meta.Tag, item.Meta.Index)
   569  			for i, rule := range rules {
   570  				t.Logf("- rule #%d: \"%v\"", i, rule)
   571  				if (rule.MacipRule.SourceAddress == "192.168.0.1") &&
   572  					(rule.MacipRule.SourceAddressPrefix == 16) &&
   573  					strings.EqualFold(rule.MacipRule.SourceMacAddress, "11:44:0A:B8:4A:35") &&
   574  					(rule.MacipRule.SourceMacAddressMask == "ff:ff:ff:ff:00:00") {
   575  					isPresent = true
   576  					break
   577  				}
   578  			}
   579  			// check assignation to interface
   580  			t.Logf("- item: %v", item)
   581  			t.Logf("%v", item.ACL.Interfaces)
   582  			for _, intf := range item.ACL.Interfaces.Ingress {
   583  				if intf == ifName {
   584  					isForInterface = true
   585  					break
   586  				}
   587  			}
   588  		}
   589  	}
   590  	Expect(isPresent).To(BeTrue(), "Configured IP should be present")
   591  	Expect(isForInterface).To(BeTrue(), "acl should be assigned to interface")
   592  
   593  	indexes := []uint32{ifIdx, ifIdx2}
   594  	ifaces, errI3 := h.DumpACLInterfaces(indexes)
   595  	Expect(errI3).To(Succeed())
   596  	Expect(ifaces).To(HaveLen(2))
   597  	t.Logf("%v", ifaces)
   598  	t.Logf("%v", ifaces[1])
   599  	t.Logf("%v", ifaces[2])
   600  	//this does not work for VPP 19.04 and maybe also other version
   601  	//checked for VPP 22.02 - still does not work
   602  	//Expect(ifaces[0].Ingress).To(Equal([]string{ifName}))
   603  	//Expect(ifaces[2].Egress).To(Equal([]string{ifName2}))
   604  
   605  	//negative tests - it is expected failure
   606  	t.Logf("Let us test some negative cases....")
   607  	_, err = h.AddMACIPACL([]*acl.ACL_Rule{}, "test7")
   608  	Expect(err).To(Not(BeNil()))
   609  	t.Logf("adding acls failed: %v", err)
   610  
   611  	_, err = h.AddMACIPACL([]*acl.ACL_Rule{newACLMacIPRule(true, "192.168.0.1", 16, "", "ff:ff:ff:ff:00:00")}, "test8")
   612  	Expect(err).To(Not(BeNil()))
   613  	t.Logf("adding acls failed: %v", err)
   614  
   615  	_, err = h.AddMACIPACL([]*acl.ACL_Rule{newACLMacIPRule(true, "192.168.0.1", 16, "11:44:0A:B8:4A:36", "")}, "test9")
   616  	Expect(err).To(Not(BeNil()))
   617  	t.Logf("adding acls failed: %v", err)
   618  
   619  	_, err = h.AddMACIPACL([]*acl.ACL_Rule{newACLMacIPRule(true, "", 16, "11:44:0A:B8:4A:36", "ff:ff:ff:ff:00:00")}, "test10")
   620  	Expect(err).To(Not(BeNil()))
   621  	Expect(err.Error()).To(BeEquivalentTo("invalid IP address "))
   622  	t.Logf("adding acls failed: %v", err)
   623  
   624  	// now let us add the same aclMACIPrules again
   625  	//add the same acls again but it will be assigned to the second interface
   626  	t.Log("Now let us add the second acl to the second interface")
   627  	const aclname2 = "test11"
   628  	aclIdx, err = h.AddMACIPACL([]*acl.ACL_Rule{
   629  		//RuleName:  "denyIPv4",
   630  		newACLMacIPRule(false, "192.168.0.1", 16, "11:44:0A:B8:4A:35", "ff:ff:ff:ff:00:00"),
   631  		//RuleName:  "denyIPv6",
   632  		newACLMacIPRule(false, "dead::1", 64, "11:44:0A:B8:4A:35", "ff:ff:ff:ff:00:00"),
   633  	}, aclname2)
   634  	Expect(err).To(BeNil())
   635  	Expect(aclIdx).To(BeEquivalentTo(1))
   636  	t.Logf("acl \"%v\" added - its index %d", aclname2, aclIdx)
   637  
   638  	err = h.AddMACIPACLToInterface(aclIdx, ifName2)
   639  	Expect(err).To(BeNil())
   640  	t.Logf("acl with index %d was assigned to interface %v ", aclIdx, ifName2)
   641  
   642  	acls, errx = h.DumpMACIPACL()
   643  	Expect(errx).To(BeNil())
   644  	Expect(acls).Should(HaveLen(2))
   645  	t.Log("amount of acls dumped: 2")
   646  
   647  	isPresent = false
   648  	isForInterface = false
   649  	for _, item := range acls {
   650  		rules = item.ACL.Rules
   651  		if (item.Meta.Index == aclIdx) && (aclname2 == item.Meta.Tag) {
   652  			t.Logf("found ACL \"%v\"", item.Meta.Tag)
   653  			for _, rule := range rules {
   654  				if (rule.MacipRule.SourceAddress == "192.168.0.1") &&
   655  					(rule.MacipRule.SourceAddressPrefix == 16) &&
   656  					strings.EqualFold(rule.MacipRule.SourceMacAddress, "11:44:0A:B8:4A:35") &&
   657  					(rule.MacipRule.SourceMacAddressMask == "ff:ff:ff:ff:00:00") {
   658  					isPresent = true
   659  					break
   660  				}
   661  			}
   662  			// check assignation to interface
   663  			t.Logf("%v", item)
   664  			t.Logf("%v", item.ACL.Interfaces)
   665  			for _, intf := range item.ACL.Interfaces.Ingress {
   666  				if intf == ifName2 {
   667  					isForInterface = true
   668  					break
   669  				}
   670  			}
   671  		}
   672  	}
   673  	Expect(isPresent).To(BeTrue(), "Configured IP should be present")
   674  	Expect(isForInterface).To(BeTrue(), "acl should be assigned to interface")
   675  
   676  	//negative tests
   677  	err = h.DeleteMACIPACL(5)
   678  	Expect(err).To(Not(BeNil()))
   679  	t.Logf("deleting acls failed: %v", err)
   680  
   681  	// find the acl with aclname test6
   682  	var foundaclidx uint32
   683  	for _, item := range acls {
   684  		if aclname == item.Meta.Tag {
   685  			foundaclidx = item.Meta.Index
   686  			break
   687  		}
   688  	}
   689  	err = h.DeleteMACIPACL(foundaclidx)
   690  	Expect(err).To(BeNil())
   691  	t.Logf("deleting of acl \"%v\" succeed", aclname)
   692  
   693  	acls, errx = h.DumpMACIPACL()
   694  	Expect(errx).To(BeNil())
   695  	Expect(acls).Should(HaveLen(1))
   696  	t.Log("amount of acls dumped: 1")
   697  
   698  	for _, aclrecord := range acls {
   699  		if aclrecord.Meta.Index == foundaclidx {
   700  			t.Fatalf("This acll should be deleted : %v", errx)
   701  		}
   702  	}
   703  
   704  	// MODIFY ACL
   705  	rule2modify := []*acl.ACL_Rule{
   706  		// acl.ACL_Rule_DENY
   707  		newACLMacIPRule(false, "192.168.10.1", 24, "11:44:0A:B8:4A:37", "ff:ff:ff:ff:00:00"),
   708  		newACLMacIPRule(false, "dead::2", 64, "11:44:0A:B8:4A:38", "ff:ff:ff:ff:00:00"),
   709  	}
   710  
   711  	const aclname4 = "test_modify0"
   712  	err = h.ModifyMACIPACL(1, rule2modify, aclname4)
   713  	Expect(err).To(BeNil())
   714  	t.Logf("modifying of acl with index 1 succeed - the new name of acl is  \"%v\"", aclname4)
   715  
   716  	acls, errx = h.DumpMACIPACL()
   717  	Expect(errx).To(BeNil())
   718  	Expect(acls).Should(HaveLen(1))
   719  	t.Log("amount of acls dumped: 1")
   720  
   721  	isPresent = false
   722  	isForInterface = false
   723  	var modifiedacl aclplugin_vppcalls.ACLDetails
   724  	for _, item := range acls {
   725  		modifiedacl = *item
   726  		rules = item.ACL.Rules
   727  		if item.Meta.Index == aclIdx && (aclname4 == item.Meta.Tag) {
   728  			t.Logf("Found modified ACL \"%v\"", item.Meta.Tag)
   729  			for _, rule := range rules {
   730  				if (rule.MacipRule.SourceAddress == "192.168.0.1") &&
   731  					(rule.MacipRule.SourceAddressPrefix == 16) &&
   732  					strings.EqualFold(rule.MacipRule.SourceMacAddress, "11:44:0A:B8:4A:35") &&
   733  					(rule.MacipRule.SourceMacAddressMask == "ff:ff:ff:ff:00:00") {
   734  					t.Fatal("Old rules should not be present")
   735  				}
   736  				if (rule.MacipRule.SourceAddress == "192.168.10.1") &&
   737  					(rule.MacipRule.SourceAddressPrefix == 24) &&
   738  					strings.EqualFold(rule.MacipRule.SourceMacAddress, "11:44:0A:B8:4A:37") &&
   739  					(rule.MacipRule.SourceMacAddressMask == "ff:ff:ff:ff:00:00") {
   740  					isPresent = true
   741  					break
   742  				}
   743  				//t.Logf("%+v", rule)
   744  			}
   745  			// check assignation to interface
   746  			for _, intf := range item.ACL.Interfaces.Ingress {
   747  				if intf == ifName2 {
   748  					isForInterface = true
   749  					break
   750  				}
   751  			}
   752  		}
   753  	}
   754  	Expect(isPresent).To(BeTrue(), "Configured IP should be present")
   755  	Expect(isForInterface).To(BeTrue(), "acl should be assigned to interface")
   756  
   757  	t.Logf("%v", modifiedacl)
   758  
   759  	// negative test
   760  	err = h.ModifyMACIPACL(1, []*acl.ACL_Rule{newACLIPRule(true, ".0.", "10.20.0.0/24")}, "test_modify1")
   761  	Expect(err).To(Not(BeNil()))
   762  	t.Logf("modifying of acl failed: %v", err)
   763  
   764  	err = h.ModifyMACIPACL(1, []*acl.ACL_Rule{
   765  		//RuleName:  "permitIPv4",
   766  		newACLIPRule(true, "192.168.1.1/32", "10.20.0.0/24"),
   767  		//RuleName:  "permitIPv6",
   768  		newACLIPRule(true, "dead::1/64", "dead::2/64"),
   769  		//RuleName:  "permitIP",
   770  		newACLIPRule(true, "", ""),
   771  		//RuleName:  "denyICMP",
   772  		newACLIPRuleIcmp(false, false, 150, 250, 1150, 1250),
   773  		//RuleName:  "denyICMPv6",
   774  		newACLIPRuleIcmp(false, true, 150, 250, 1150, 1250),
   775  		//RuleName:  "permitTCP",
   776  		newACLIPRuleTCP(true, 10, 20, 150, 250, 1150, 1250),
   777  		//RuleName:  "denyUDP",
   778  		newACLIPRuleUDP(false, 150, 250, 1150, 1250),
   779  	}, "test_modify5")
   780  	Expect(err).To(Not(BeNil()))
   781  	t.Logf("modifying of acl failed: %v", err)
   782  
   783  	err = h.SetMACIPACLToInterfaces(aclIdx, []uint32{ifIdx})
   784  	Expect(err).To(BeNil())
   785  	t.Logf("acl with index %d was assigned to interface %v", aclIdx, ifName)
   786  
   787  	acls, errx = h.DumpMACIPACL()
   788  	Expect(errx).To(BeNil())
   789  	Expect(acls).Should(HaveLen(1))
   790  	t.Log("amount of acls dumped: 1")
   791  
   792  	isForInterface = false
   793  	for _, item := range acls {
   794  		if item.Meta.Index == aclIdx {
   795  			t.Logf("found modified ACL \"%v\"", item.Meta.Tag)
   796  			// check assignation to interface
   797  			t.Logf("%v", item)
   798  			t.Logf("%v", item.ACL.Interfaces)
   799  			for _, intf := range item.ACL.Interfaces.Ingress {
   800  				if intf == ifName {
   801  					isForInterface = true
   802  					break
   803  				}
   804  			}
   805  		}
   806  	}
   807  	Expect(isForInterface).To(BeTrue(), "acl should be assigned to interface")
   808  
   809  	err = h.SetMACIPACLToInterfaces(aclIdx, []uint32{ifIdx})
   810  	Expect(err).To(BeNil())
   811  	t.Logf("acl with index %d was assigned to interface %v", aclIdx, ifName)
   812  
   813  	acls, errx = h.DumpMACIPACL()
   814  	Expect(errx).To(BeNil())
   815  	Expect(acls).Should(HaveLen(1))
   816  	t.Log("amount of acls dumped: 1")
   817  
   818  	isForInterface = false
   819  	for _, item := range acls {
   820  		if item.Meta.Index == aclIdx {
   821  			t.Logf("found modified ACL \"%v\"", item.Meta.Tag)
   822  			// check assignation to interface
   823  			t.Logf("%v", item)
   824  			t.Logf("%v", item.ACL.Interfaces)
   825  			for _, intf := range item.ACL.Interfaces.Ingress {
   826  				if intf == ifName {
   827  					isForInterface = true
   828  					break
   829  				}
   830  			}
   831  		}
   832  	}
   833  	Expect(isForInterface).To(BeTrue(), "acl should be assigned to interface")
   834  
   835  	err = h.DeleteMACIPACLFromInterface(aclIdx, ifName)
   836  	Expect(err).To(BeNil())
   837  	t.Logf("for acl with index %d was deleted the relation to interface %v", aclIdx, ifName)
   838  
   839  	acls, errx = h.DumpMACIPACL()
   840  	Expect(errx).To(BeNil())
   841  	Expect(acls).Should(HaveLen(1))
   842  	t.Log("amount of acls dumped: 1")
   843  
   844  	for _, item := range acls {
   845  		if item.Meta.Index == aclIdx {
   846  			t.Logf("Found modified ACL \"%v\"", item.Meta.Tag)
   847  			// check assignation to interface
   848  			t.Logf("%v", item)
   849  			t.Logf("%v", item.ACL.Interfaces)
   850  			for _, intf := range item.ACL.Interfaces.Ingress {
   851  				if intf == ifName {
   852  					t.Fatalf("acl should not be assigned to the interface %v", ifName)
   853  				}
   854  			}
   855  		}
   856  	}
   857  	t.Logf("for acl was correctly deleted relation to interface %v", ifName)
   858  
   859  	err = h.DeleteMACIPACLFromInterface(aclIdx, ifName2)
   860  	Expect(err).To(BeNil())
   861  	t.Logf("for acl with index %d was deleted the relation to interface %v", aclIdx, ifName2)
   862  
   863  	acls, errx = h.DumpMACIPACL()
   864  	Expect(errx).To(BeNil())
   865  	Expect(acls).Should(HaveLen(1))
   866  	t.Log("amount of acls dumped: 1")
   867  
   868  	for _, item := range acls {
   869  		if item.Meta.Index == aclIdx {
   870  			t.Logf("Found modified ACL \"%v\"", item.Meta.Tag)
   871  			// check assignation to interface
   872  			t.Logf("%v", item)
   873  			t.Logf("%v", item.ACL.Interfaces)
   874  			Expect(item.ACL.Interfaces).To(BeNil())
   875  		}
   876  	}
   877  	t.Logf("for acl was correctly deleted relation to interface %v", ifName2)
   878  
   879  	acls, errx = h.DumpMACIPACL()
   880  	Expect(errx).To(BeNil())
   881  	Expect(acls).Should(HaveLen(1))
   882  	t.Log("amount of acls dumped: 1")
   883  
   884  	for _, aclrecord := range acls {
   885  		foundaclidx = aclrecord.Meta.Index
   886  	}
   887  
   888  	err = h.DeleteMACIPACL(foundaclidx)
   889  	Expect(err).To(BeNil())
   890  	t.Logf("deleting acl succeed")
   891  
   892  	acls, errx = h.DumpMACIPACL()
   893  	Expect(errx).To(BeNil())
   894  	Expect(acls).Should(BeEmpty())
   895  	t.Log("no acls dumped")
   896  }