github.com/vishvananda/netlink@v1.3.0/xfrm_policy_linux_test.go (about)

     1  package netlink
     2  
     3  import (
     4  	"bytes"
     5  	"net"
     6  	"testing"
     7  )
     8  
     9  const zeroCIDR = "0.0.0.0/0"
    10  
    11  func TestXfrmPolicyAddUpdateDel(t *testing.T) {
    12  	tearDown := setUpNetlinkTest(t)
    13  	defer tearDown()
    14  
    15  	policy := getPolicy()
    16  	if err := XfrmPolicyAdd(policy); err != nil {
    17  		t.Fatal(err)
    18  	}
    19  	policies, err := XfrmPolicyList(FAMILY_ALL)
    20  	if err != nil {
    21  		t.Fatal(err)
    22  	}
    23  
    24  	if len(policies) != 1 {
    25  		t.Fatal("Policy not added properly")
    26  	}
    27  
    28  	if !comparePolicies(policy, &policies[0]) {
    29  		t.Fatalf("unexpected policy returned.\nExpected: %v.\nGot %v", policy, policies[0])
    30  	}
    31  
    32  	if policies[0].Ifindex != 0 {
    33  		t.Fatalf("default policy has a non-zero interface index.\nGot %d", policies[0].Ifindex)
    34  	}
    35  
    36  	if policies[0].Ifid != 0 {
    37  		t.Fatalf("default policy has non-zero if_id.\nGot %d", policies[0].Ifid)
    38  	}
    39  
    40  	if policies[0].Action != XFRM_POLICY_ALLOW {
    41  		t.Fatalf("default policy has non-allow action.\nGot %s", policies[0].Action)
    42  	}
    43  
    44  	// Look for a specific policy
    45  	sp, err := XfrmPolicyGet(policy)
    46  	if err != nil {
    47  		t.Fatal(err)
    48  	}
    49  
    50  	if !comparePolicies(policy, sp) {
    51  		t.Fatalf("unexpected policy returned")
    52  	}
    53  
    54  	// Modify the policy
    55  	policy.Priority = 100
    56  	if err := XfrmPolicyUpdate(policy); err != nil {
    57  		t.Fatal(err)
    58  	}
    59  	sp, err = XfrmPolicyGet(policy)
    60  	if err != nil {
    61  		t.Fatal(err)
    62  	}
    63  	if sp.Priority != 100 {
    64  		t.Fatalf("failed to modify the policy")
    65  	}
    66  
    67  	if err = XfrmPolicyDel(policy); err != nil {
    68  		t.Fatal(err)
    69  	}
    70  
    71  	policies, err = XfrmPolicyList(FAMILY_ALL)
    72  	if err != nil {
    73  		t.Fatal(err)
    74  	}
    75  	if len(policies) != 0 {
    76  		t.Fatal("Policy not removed properly")
    77  	}
    78  
    79  	// Src and dst are not mandatory field. Creation should succeed
    80  	policy.Src = nil
    81  	policy.Dst = nil
    82  	if err = XfrmPolicyAdd(policy); err != nil {
    83  		t.Fatal(err)
    84  	}
    85  
    86  	sp, err = XfrmPolicyGet(policy)
    87  	if err != nil {
    88  		t.Fatal(err)
    89  	}
    90  
    91  	if !comparePolicies(policy, sp) {
    92  		t.Fatalf("unexpected policy returned")
    93  	}
    94  
    95  	if err = XfrmPolicyDel(policy); err != nil {
    96  		t.Fatal(err)
    97  	}
    98  
    99  	if _, err := XfrmPolicyGet(policy); err == nil {
   100  		t.Fatalf("Unexpected success")
   101  	}
   102  }
   103  
   104  func TestXfrmPolicyFlush(t *testing.T) {
   105  	defer setUpNetlinkTest(t)()
   106  
   107  	p1 := getPolicy()
   108  	if err := XfrmPolicyAdd(p1); err != nil {
   109  		t.Fatal(err)
   110  	}
   111  
   112  	p1.Dir = XFRM_DIR_IN
   113  	s := p1.Src
   114  	p1.Src = p1.Dst
   115  	p1.Dst = s
   116  	if err := XfrmPolicyAdd(p1); err != nil {
   117  		t.Fatal(err)
   118  	}
   119  
   120  	policies, err := XfrmPolicyList(FAMILY_ALL)
   121  	if err != nil {
   122  		t.Fatal(err)
   123  	}
   124  	if len(policies) != 2 {
   125  		t.Fatalf("unexpected number of policies: %d", len(policies))
   126  	}
   127  
   128  	if err := XfrmPolicyFlush(); err != nil {
   129  		t.Fatal(err)
   130  	}
   131  
   132  	policies, err = XfrmPolicyList(FAMILY_ALL)
   133  	if err != nil {
   134  		t.Fatal(err)
   135  	}
   136  	if len(policies) != 0 {
   137  		t.Fatalf("unexpected number of policies: %d", len(policies))
   138  	}
   139  
   140  }
   141  
   142  func TestXfrmPolicyBlockWithIfindex(t *testing.T) {
   143  	defer setUpNetlinkTest(t)()
   144  
   145  	pBlock := getPolicy()
   146  	pBlock.Action = XFRM_POLICY_BLOCK
   147  	pBlock.Ifindex = 1 // loopback interface
   148  	if err := XfrmPolicyAdd(pBlock); err != nil {
   149  		t.Fatal(err)
   150  	}
   151  	policies, err := XfrmPolicyList(FAMILY_ALL)
   152  	if err != nil {
   153  		t.Fatal(err)
   154  	}
   155  	if len(policies) != 1 {
   156  		t.Fatalf("unexpected number of policies: %d", len(policies))
   157  	}
   158  	if !comparePolicies(pBlock, &policies[0]) {
   159  		t.Fatalf("unexpected policy returned.\nExpected: %v.\nGot %v", pBlock, policies[0])
   160  	}
   161  	if err = XfrmPolicyDel(pBlock); err != nil {
   162  		t.Fatal(err)
   163  	}
   164  }
   165  
   166  func TestXfrmPolicyWithIfid(t *testing.T) {
   167  	minKernelRequired(t, 4, 19)
   168  	defer setUpNetlinkTest(t)()
   169  
   170  	pol := getPolicy()
   171  	pol.Ifid = 54321
   172  
   173  	if err := XfrmPolicyAdd(pol); err != nil {
   174  		t.Fatal(err)
   175  	}
   176  	policies, err := XfrmPolicyList(FAMILY_ALL)
   177  	if err != nil {
   178  		t.Fatal(err)
   179  	}
   180  	if len(policies) != 1 {
   181  		t.Fatalf("unexpected number of policies: %d", len(policies))
   182  	}
   183  	if !comparePolicies(pol, &policies[0]) {
   184  		t.Fatalf("unexpected policy returned.\nExpected: %v.\nGot %v", pol, policies[0])
   185  	}
   186  	if err = XfrmPolicyDel(&policies[0]); err != nil {
   187  		t.Fatal(err)
   188  	}
   189  }
   190  
   191  func TestXfrmPolicyWithOptional(t *testing.T) {
   192  	minKernelRequired(t, 4, 19)
   193  	defer setUpNetlinkTest(t)()
   194  
   195  	pol := getPolicy()
   196  	pol.Dir = XFRM_DIR_IN
   197  	pol.Tmpls[0].Optional = 1
   198  
   199  	if err := XfrmPolicyAdd(pol); err != nil {
   200  		t.Fatal(err)
   201  	}
   202  	policies, err := XfrmPolicyList(FAMILY_ALL)
   203  	if err != nil {
   204  		t.Fatal(err)
   205  	}
   206  	if len(policies) != 1 {
   207  		t.Fatalf("unexpected number of policies: %d", len(policies))
   208  	}
   209  	if !comparePolicies(pol, &policies[0]) {
   210  		t.Fatalf("unexpected policy returned.\nExpected: %v.\nGot %v", pol, policies[0])
   211  	}
   212  	if err = XfrmPolicyDel(&policies[0]); err != nil {
   213  		t.Fatal(err)
   214  	}
   215  }
   216  
   217  func comparePolicies(a, b *XfrmPolicy) bool {
   218  	if a == b {
   219  		return true
   220  	}
   221  	if a == nil || b == nil {
   222  		return false
   223  	}
   224  	// Do not check Index which is assigned by kernel
   225  	return a.Dir == b.Dir && a.Priority == b.Priority &&
   226  		compareIPNet(a.Src, b.Src) && compareIPNet(a.Dst, b.Dst) &&
   227  		a.Action == b.Action && a.Ifindex == b.Ifindex &&
   228  		a.Mark.Value == b.Mark.Value && a.Mark.Mask == b.Mark.Mask &&
   229  		a.Ifid == b.Ifid && compareTemplates(a.Tmpls, b.Tmpls)
   230  }
   231  
   232  func compareTemplates(a, b []XfrmPolicyTmpl) bool {
   233  	if len(a) != len(b) {
   234  		return false
   235  	}
   236  	for i, ta := range a {
   237  		tb := b[i]
   238  		if !ta.Dst.Equal(tb.Dst) || !ta.Src.Equal(tb.Src) || ta.Spi != tb.Spi ||
   239  			ta.Mode != tb.Mode || ta.Reqid != tb.Reqid || ta.Proto != tb.Proto ||
   240  			ta.Optional != tb.Optional {
   241  			return false
   242  		}
   243  	}
   244  	return true
   245  }
   246  
   247  func compareIPNet(a, b *net.IPNet) bool {
   248  	if a == b {
   249  		return true
   250  	}
   251  	// For unspecified src/dst parseXfrmPolicy would set the zero address cidr
   252  	if (a == nil && b.String() == zeroCIDR) || (b == nil && a.String() == zeroCIDR) {
   253  		return true
   254  	}
   255  	if a == nil || b == nil {
   256  		return false
   257  	}
   258  	return a.IP.Equal(b.IP) && bytes.Equal(a.Mask, b.Mask)
   259  }
   260  
   261  func getPolicy() *XfrmPolicy {
   262  	src, _ := ParseIPNet("127.1.1.1/32")
   263  	dst, _ := ParseIPNet("127.1.1.2/32")
   264  	policy := &XfrmPolicy{
   265  		Src:     src,
   266  		Dst:     dst,
   267  		Proto:   17,
   268  		DstPort: 1234,
   269  		SrcPort: 5678,
   270  		Dir:     XFRM_DIR_OUT,
   271  		Mark: &XfrmMark{
   272  			Value: 0xabff22,
   273  			Mask:  0xffffffff,
   274  		},
   275  		Priority: 10,
   276  	}
   277  	tmpl := XfrmPolicyTmpl{
   278  		Src:   net.ParseIP("127.0.0.1"),
   279  		Dst:   net.ParseIP("127.0.0.2"),
   280  		Proto: XFRM_PROTO_ESP,
   281  		Mode:  XFRM_MODE_TUNNEL,
   282  		Spi:   0x1bcdef99,
   283  	}
   284  	policy.Tmpls = append(policy.Tmpls, tmpl)
   285  	return policy
   286  }