Skip to content

Commit

Permalink
Make port speed configurable (in EOS as well)
Browse files Browse the repository at this point in the history
As the driver is fully responsible for its own switchports, we use a
replace config call via GNMI to configure those ports. This means that
there is - at the moment - no option for manual configuration of these
interfaces. This means that we now also need to be able to configure
interface port speeds.

Config-wise this means that we just have a string, which might be
vendor-specific, but at least understandable by the platform's agent. In
the eos case we translate speeds like 10/100g to their respective API
values (SPEED_10GB, SPEED_100GB).
  • Loading branch information
sebageek committed Dec 11, 2023
1 parent df890d3 commit fda3556
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 7 deletions.
3 changes: 3 additions & 0 deletions networking_ccloud/common/config/config_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ class SwitchPort(pydantic.BaseModel):
members: List[str] = None
unmanaged: bool = False

# set interface (or member interface) speed to this vendor specific value
speed: str = None

@pydantic.root_validator
def only_allow_members_and_pc_id_with_lacp_enabled(cls, v):
if v['members'] and not v['lacp']:
Expand Down
3 changes: 2 additions & 1 deletion networking_ccloud/ml2/agent/common/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ class IfaceConfig(pydantic.BaseModel):
vlan_translations: List[VlanTranslation] = None
portchannel_id: pydantic.conint(gt=0) = None
members: List[str] = None
speed: str = None

def __lt__(self, other):
return self.name < other.name
Expand All @@ -244,7 +245,7 @@ def sort(self):

@classmethod
def from_switchport(cls, switchport):
iface = cls(name=switchport.name)
iface = cls(name=switchport.name, speed=switchport.speed)
if switchport.lacp:
iface.portchannel_id = switchport.portchannel_id
iface.members = switchport.members
Expand Down
9 changes: 9 additions & 0 deletions networking_ccloud/ml2/agent/eos/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,15 @@ def remove_stale_vlan_translations(ifname, iface_cfg, is_pc):
data['switched-vlan'] = switched_vlan_config
if iface.vlan_translations:
remove_stale_vlan_translations(iface_name, iface, is_pc=False)
if iface.speed:
if iface.speed in ('1g', '10g', '25g', '40g', '100g', '400g'):
eth_config = data.setdefault('config', {})
eth_config['port-speed'] = f"SPEED_{iface.speed.upper()}B"
eth_config['auto-negotiate'] = False
eth_config['duplex-mode'] = 'FULL'
else:
LOG.warning('Invalid interface speed "%s" for interface %s, ignoring it',
iface.speed, iface.name)
iface_cfg = (EOSGNMIPaths.IFACE_ETH.format(iface=iface_name), data)
config_req.get_list(operation).append(iface_cfg)
else:
Expand Down
60 changes: 54 additions & 6 deletions networking_ccloud/tests/unit/ml2/agent/eos/test_switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,47 @@ def _get(prefix, unpack=True):
{'config': {'bridging-vlan': 1001,
'translation-key': 1337},
'translation-key': 1337}]}}}),
('interfaces/interface[name=Port-Channel42]', {
'config': {
'name': 'Port-Channel42',
'type': 'iana-if-type:ieee8023adLag'
},
'name': 'Port-Channel42',
'aggregation': {
'config': {
'fallback': 'individual',
'mlag': 42,
'fallback-timeout': 50,
'lag-type': 'LACP',
},
'switched-vlan': {
'config': {
'interface-mode': 'TRUNK',
'native-vlan': 1000,
'trunk-vlans': ['667'],
},
}
}
}),
('interfaces/interface[name=Ethernet5/1]/ethernet',
{'config': {'aggregate-id': 'Port-Channel42',
'port-speed': 'SPEED_25GB', 'auto-negotiate': False, 'duplex-mode': 'FULL'},
'switched-vlan': {'config': {'interface-mode': 'TRUNK',
'native-vlan': 1000,
'trunk-vlans': ['667']}}}),
('interfaces/interface[name=Ethernet5/2]/ethernet',
{'config': {'aggregate-id': 'Port-Channel42',
'port-speed': 'SPEED_25GB', 'auto-negotiate': False, 'duplex-mode': 'FULL'},
'switched-vlan': {'config': {'interface-mode': 'TRUNK',
'native-vlan': 1000,
'trunk-vlans': ['667']}}}),
('interfaces/interface[name=Ethernet23/1]/ethernet',
{'switched-vlan': {'config': {'interface-mode': 'TRUNK',
'trunk-vlans': ['1001']}}}),
('interfaces/interface[name=Ethernet23/2]/ethernet',
{'config': {'port-speed': 'SPEED_100GB', 'auto-negotiate': False, 'duplex-mode': 'FULL'},
'switched-vlan': {'config': {'interface-mode': 'TRUNK',
'trunk-vlans': ['1001']}}}),
('interfaces/interface[name=Vlan2337]',
{'name': 'Vlan2337', 'config': {'name': 'Vlan2337', 'type': 'l3ipvlan'},
'arista-varp': {'virtual-address': {'config': {'ip': '1.1.1.1', 'prefix-length': 24}}}}),
Expand Down Expand Up @@ -234,16 +272,26 @@ def _get(prefix, unpack=True):
cu.bgp.add_vlan(1000, 232323, 1)

# interfaces
iface1 = messages.IfaceConfig(name="Port-Channel23", portchannel_id=23, native_vlan=1000,
members=["Ethernet4/1", "Ethernet4/2"])
iface1.add_trunk_vlan(1000)
pc1 = messages.IfaceConfig(name="Port-Channel23", portchannel_id=23, native_vlan=1000,
members=["Ethernet4/1", "Ethernet4/2"])
pc1.add_trunk_vlan(1000)
pc1.add_trunk_vlan(1001)
pc1.add_vlan_translation(1000, 2323)
pc1.add_vlan_translation(1001, 1337)
cu.add_iface(pc1)

pc2 = messages.IfaceConfig(name="Port-Channel42", portchannel_id=42, native_vlan=1000,
members=["Ethernet5/1", "Ethernet5/2"], speed='25g')
pc2.add_trunk_vlan(667)
cu.add_iface(pc2)

iface1 = messages.IfaceConfig(name="Ethernet23/1")
iface1.add_trunk_vlan(1001)
iface1.add_vlan_translation(1000, 2323)
iface1.add_vlan_translation(1001, 1337)
cu.add_iface(iface1)

iface2 = messages.IfaceConfig(name="Ethernet23/1")
iface2 = messages.IfaceConfig(name="Ethernet23/2")
iface2.add_trunk_vlan(1001)
iface2.speed = "100g"
cu.add_iface(iface2)

# vlan iface + vrf
Expand Down

0 comments on commit fda3556

Please sign in to comment.