From 6688c6b24395b5262c1952515e981d8cb36d422a Mon Sep 17 00:00:00 2001
From: Pim van Pelt <pim@ipng.nl>
Date: Tue, 22 Mar 2022 14:21:30 +0000
Subject: [PATCH] Add the case of the ifname being the source of an l2xc to the
 is_l2() logic1

This is more strict than VPP itself, which does allow a destination to
be L3 while the source is L2:

DBGvpp# show mode
l3 local0
l3 GigabitEthernet3/0/0
l3 GigabitEthernet3/0/1
l3 HundredGigabitEthernet12/0/0
l3 HundredGigabitEthernet12/0/1

DBGvpp# set interface l2 xconnect GigabitEthernet3/0/0 GigabitEthernet3/0/1

DBGvpp# show mode
l3 local0
l2 xconnect GigabitEthernet3/0/0 GigabitEthernet3/0/1
l3 GigabitEthernet3/0/1
l3 HundredGigabitEthernet12/0/0
l3 HundredGigabitEthernet12/0/1

But it seems undesirable to have Gi3/0/1 be in l3 mode even though it's
the target of a cross connect, so I'm going to leave the behavior
stricter than VPP.
---
 validator/interface.py      | 4 +++-
 validator/test_interface.py | 2 ++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/validator/interface.py b/validator/interface.py
index e33eec1..60afa42 100644
--- a/validator/interface.py
+++ b/validator/interface.py
@@ -307,9 +307,11 @@ def unique_encapsulation(yaml, sub_ifname):
 
 
 def is_l2(yaml, ifname):
-    """ Returns True if the interface is an L2XC target or a member of a bridgedomain """
+    """ Returns True if the interface is an L2XC source, L2XC target or a member of a bridgedomain """
     if bridgedomain.is_bridge_interface(yaml, ifname):
         return True
+    if is_l2xc_interface(yaml, ifname):
+        return True
     if is_l2xc_target_interface(yaml, ifname):
         return True
     return False
diff --git a/validator/test_interface.py b/validator/test_interface.py
index fb9a94a..3d02bbd 100644
--- a/validator/test_interface.py
+++ b/validator/test_interface.py
@@ -125,6 +125,8 @@ class TestInterfaceMethods(unittest.TestCase):
     def test_l2(self):
         self.assertTrue(interface.is_l2(self.cfg, "GigabitEthernet3/0/0"))
         self.assertFalse(interface.is_l2(self.cfg, "GigabitEthernet1/0/0"))
+        self.assertTrue(interface.is_l2(self.cfg, "GigabitEthernet3/0/2.100"))
+        self.assertTrue(interface.is_l2(self.cfg, "GigabitEthernet3/0/2.200"))
 
     def test_l3(self):
         self.assertTrue(interface.is_l3(self.cfg, "GigabitEthernet1/0/0"))